Set options and working directory

Load libraries

library(Seurat)
library(cowplot)
library(umap)
library(dplyr)
library(Matrix)
library(readxl)
library(openxlsx)
library(ggplot2)
library(ggrepel)
library(ggpubr)
library(sctransform)
library(knitr)
library(kableExtra)
#library(biomaRt)
library(DESeq2)
library(escape)
library(dittoSeq)
library(GSEABase)
library(scater)
library(ComplexHeatmap)

Import marker sets

gene.lists <- read_xlsx("Munoz_Yilmaz_CellCycle_signatures.xlsx")
gene.lists.names <- colnames(gene.lists)
GOI.lists <- c()
for (i in gene.lists.names) {
  tmpList <- gene.lists %>% dplyr::select(all_of(i))
  tmpList <- tmpList[!is.na(tmpList)]
  GOI.lists[[i]] <- tmpList
}

Load the Cell Ranger Matrix Data and create the base Seurat object.*

the initial processing was done with r 3.6.1 with Seurat 3.2.0 - the UMAP comes out slightly differently in r 4.0.3 with Seurat 3.2.3*

#al.dat <- Read10X("200218Yil_data/al/filtered_feature_bc_matrix/")
#f.dat <- Read10X("200218Yil_data/f/filtered_feature_bc_matrix/")
#rf.dat <- Read10X("200218Yil_data/rf/filtered_feature_bc_matrix/")
#rf.rapa.dat <- Read10X("200218Yil_data/rf.rapa/filtered_feature_bc_matrix/")

#al <- CreateSeuratObject(counts = al.dat, project = "al", min.cells = 3, min.features = 200)
#f <- CreateSeuratObject(counts = f.dat, project = "f", min.cells = 3, min.features = 200)
#rf <- CreateSeuratObject(counts = rf.dat, project = "rf", min.cells = 3, min.features = 200)
#rf.rapa <- CreateSeuratObject(counts = rf.rapa.dat, project = "rf.rapa", min.cells = 3, min.features = 200)

#al[["percent.mt"]] <- PercentageFeatureSet(al, pattern = "^mt-")
#f[["percent.mt"]] <- PercentageFeatureSet(f, pattern = "^mt-")
#rf[["percent.mt"]] <- PercentageFeatureSet(rf, pattern = "^mt-")
#rf.rapa[["percent.mt"]] <- PercentageFeatureSet(rf.rapa, pattern = "^mt-")

#VlnPlot(al, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
#VlnPlot(f, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
#VlnPlot(rf, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
#VlnPlot(al, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)

Merge samples to single Seurat Object

#merged_Seu <- merge(al, c(f,rf,rf.rapa), project = "Diet")

#merged_Seu <- NormalizeData(merged_Seu, normalization.method = "LogNormalize", scale.factor = 10000)
#merged_Seu <- FindVariableFeatures(merged_Seu, selection.method = "vst", nfeatures = 2000)
#merged_Seu <- ScaleData(merged_Seu)
#merged_Seu <- RunPCA(merged_Seu, features = VariableFeatures(object = merged_Seu))
#merged_Seu <- RunUMAP(merged_Seu, reduction="pca",dims=1:30)
#merged_Seu <- RunTSNE(merged_Seu, reduction="pca",dims=1:30)
#merged_Seu <- FindNeighbors(merged_Seu, dims = 1:30, verbose = FALSE)
#merged_Seu <- FindClusters(merged_Seu, verbose = FALSE)

#DimPlot(merged_Seu,reduction="umap",group.by="orig.ident",label=TRUE,repel=FALSE)

#FeaturePlot(merged_Seu,reduction="umap",features="mt-Cytb",min.cutoff=0,max.cutoff=4,cols=c("grey","red"))
#FeaturePlot(merged_Seu,reduction="umap",features="percent.mt",cols=c("grey","red"))
#FeaturePlot(merged_Seu,reduction="umap",features="nFeature_RNA",cols=c("grey","red"))

Save/Load seurat object

#save(merged_Seu, file="merged.Robj")
#load("merged.Robj")

Dataset Integration

#di <- SplitObject(merged_Seu, split.by = "orig.ident")

#for (i in 1:length(di)) {
#  di[[i]] <- NormalizeData(di[[i]], verbose = FALSE)
#  di[[i]] <- FindVariableFeatures(di[[i]], selection.method = "vst", nfeatures = 2000,
#                                      verbose = FALSE)
#}

#dat.anchors <- FindIntegrationAnchors(object.list=di,dims=1:30)
#integrated <- IntegrateData(anchorset=dat.anchors,dim=1:30)

#DefaultAssay(integrated)<-"integrated"
#integrated <- ScaleData(integrated)
#integrated <- RunPCA(integrated,npcs=30)
#integrated <- RunUMAP(integrated,reduction="pca",dims=1:30)
#integrated <- RunTSNE(integrated,reduction="pca",dims=1:30)
#integrated <- FindNeighbors(integrated, dims = 1:30, verbose = FALSE)
#integrated <- FindClusters(integrated, verbose = FALSE)

Load integrated data and create UMAP from original integrated run*

NOTE: loading final object to avoid recalculating ssGSEA data

#load("integrated_orig.Robj")
load("../repo_data/integrated_final.Robj")

Test plots

DefaultAssay(integrated)<-"integrated"
DimPlot(integrated,reduction="umap",split.by="orig.ident",group.by="orig.ident")

DimPlot(integrated,reduction="umap",group.by="orig.ident")

DimPlot(integrated,reduction="umap",group.by="integrated_snn_res.0.8", label=TRUE)
Using `as.character()` on a quosure is deprecated as of rlang 0.3.0.
Please use `as_label()` or `as_name()` instead.

Figure 3B - Add cluster/treatment metadata columns and plot labeled UMAP

integrated@meta.data$treat_clust <- paste0(integrated@meta.data$orig.ident,integrated@meta.data$integrated_snn_res.0.8)
integrated@meta.data$clust_treat <- paste0(integrated@meta.data$integrated_snn_res.0.8,integrated@meta.data$orig.ident)
integrated@meta.data$celltype <- integrated@meta.data$integrated_snn_res.0.8
Idents(object = integrated) <- integrated$celltype

integrated <- RenameIdents(object = integrated,  '16' = '16_Tuft')
integrated <- RenameIdents(object = integrated,  '11' = '11_EC')
integrated <- RenameIdents(object = integrated,  '13' = '13_EEC')
integrated <- RenameIdents(object = integrated,  '2' = '2_Stem')
integrated <- RenameIdents(object = integrated,  '5' = '5_Stem')
integrated <- RenameIdents(object = integrated,  '10' = '10_Stem')
integrated <- RenameIdents(object = integrated,  '14' = '14_Paneth')
integrated <- RenameIdents(object = integrated,  '8' = '8_Secretory_Progenitor')
integrated <- RenameIdents(object = integrated,  '9' = '9_Goblet')
integrated <- RenameIdents(object = integrated,  '1' = '1_Secretory_Progenitor')
integrated <- RenameIdents(object = integrated,  '4' = '4_Secretory_Progenitor')
integrated <- RenameIdents(object = integrated,  '15' = '15_Secretory_Progenitor')
integrated <- RenameIdents(object = integrated,  '3' = '3_EC_Progenitor')
integrated <- RenameIdents(object = integrated,  '6' = '6_EC_Progenitor')
integrated <- RenameIdents(object = integrated,  '0' = '0_Early_TA')
integrated <- RenameIdents(object = integrated,  '7' = '7_Early_TA')
integrated <- RenameIdents(object = integrated,  '12' = '12_Unknown')


integrated[["clust_celltype"]] <- Idents(object = integrated)

Fig3b UMAP Plot with color blind safe colors

Idents(object = integrated) <- integrated$clust_celltype

celltype_colors <- c("2_Stem"="#117733",
                     "5_Stem"="#999933",
                     "10_Stem"="#009E73",
                     "0_Early_TA"="#E69F00",
                     "7_Early_TA"="#D55E00",
                     "6_EC_Progenitor"="#0072B2",
                     "3_EC_Progenitor"="#56B4E9",
                     "11_EC"="#88CCEE",
                     "13_EEC"="#6699CC",
                     "1_Secretory_Progenitor"="#661100",
                     "4_Secretory_Progenitor"="#882255",
                     "8_Secretory_Progenitor"="#CC6677",
                     "15_Secretory_Progenitor"="#AA4499",
                     "14_Paneth"="#332288",
                     "16_Tuft"="#000000",
                     "9_Goblet"="#F0E442",
                     "12_Unknown"="#999999")  

dp.cb <- DimPlot(integrated,reduction="umap", cols=celltype_colors, label=TRUE, repel=TRUE, pt.size=2, label.size=6) + NoLegend()
dp.cb


#pdf('Fig3b.cbSafe.pdf',width=14, height=10)
#dp.cb
#dev.off()

Figure 3C - LGR5 Vln plot with color blind safe colors

DefaultAssay(integrated)<-"RNA"
Idents(object = integrated) <- integrated$integrated_snn_res.0.8
plotOrder <- c("5","2","10","0","1","3","4","6","7","8","9","11","12","13","14","15","16")

vln_colors <- c("2"="#117733",
                "5"="#999933",
                "10"="#009E73",
                "0"="#E69F00",
                "1"="#661100",
                "3"="#56B4E9",
                "4"="#882255",
                "6"="#0072B2",
                "7"="#D55E00",
                "8"="#CC6677",
                "9"="#F0E442",
                "11"="#88CCEE",
                "12"="#999999",
                "13"="#6699CC",
                "14"="#332288",
                "15"="#AA4499",
                "16"="#000000")  

Idents(integrated) <- factor(Idents(integrated), levels= plotOrder)
vl.cb <- VlnPlot(integrated, cols=vln_colors, idents = , features = c("Lgr5"), pt.size = 0.5, slot="data")
vl.cb


#pdf('Fig3c_cbSafe.pdf',width=14, height=8)
#vl.cb
#dev.off()

Figure S3,B - Table of cell counts in each integrated data cluster and sample

p.integrated <- table(integrated@meta.data$integrated_snn_res.0.8,integrated@meta.data$orig.ident)
round(prop.table(p.integrated,2),3)
    
        al     f    rf rf.rapa
  0  0.169 0.191 0.135   0.178
  1  0.096 0.101 0.135   0.119
  2  0.082 0.116 0.104   0.102
  3  0.099 0.091 0.098   0.101
  4  0.125 0.078 0.082   0.061
  5  0.076 0.080 0.084   0.072
  6  0.076 0.074 0.065   0.077
  7  0.056 0.040 0.096   0.055
  8  0.078 0.053 0.034   0.037
  9  0.028 0.046 0.043   0.060
  10 0.034 0.032 0.044   0.055
  11 0.026 0.056 0.033   0.029
  12 0.039 0.028 0.024   0.032
  13 0.005 0.006 0.009   0.009
  14 0.005 0.005 0.006   0.007
  15 0.002 0.002 0.005   0.005
  16 0.004 0.002 0.004   0.001

Figure 5D - heatmap

DefaultAssay(integrated)<- "integrated"
Idents(object = integrated) <- integrated$integrated_snn_res.0.8
dd <- subset(integrated, idents = c("2", "5", "10"), downsample=100)

topvst <- head(VariableFeatures(dd), 500)
mat <- as.matrix(dd@assays$integrated@scale.data) #as.matrix(subset_dd@assays$integrated@scale.data)
mat <- mat[topvst,]

genes <- c(GOI.lists$Biton_S1_ISC.I, GOI.lists$Biton_S1_ISC.II, GOI.lists$Biton_S1_ISC.III)
labels <- c(rep('Biton ISC I', length(GOI.lists$Biton_S1_ISC.I)), 
            rep('Biton ISC II', length(GOI.lists$Biton_S1_ISC.II)), 
            rep('Biton ISC III', length(GOI.lists$Biton_S1_ISC.III)))

idxs <- which(genes %in% rownames(mat))
genes <- genes[idxs]
labels <- labels[idxs]
mat <- mat[genes,]

ht <- Heatmap(mat, column_names_side = 'top', row_names_gp = gpar(fontsize = 9), column_names_gp = gpar(fontsize = 12),
              column_title = '', name = 'scaled data', column_labels = rep('', ncol(mat)),
              column_split = factor(as.character(dd$integrated_snn_res.0.8), levels = c('5', '2', '10')), 
              row_split = labels, row_order = genes, #column_order = sort(colnames(mat)),
              cluster_column_slices = FALSE,
              top_annotation = HeatmapAnnotation(cluster = as.character(dd$integrated_snn_res.0.8)))

draw(ht)


#pdf('Fig3D.pdf',width=12, height=10)
#draw(ht)
#dev.off()

GSEA dot plots

data <- as.data.frame(read_excel('cluster_2_5_10stem_gsea.xlsx', sheet = 'Sheet2'))
data
data$FDR <- data$`FDR q-val` + 0.001
data$Comparison <- gsub('\\.noNA\\.NES','',data$Comparison)

comparisons <- c('f5_v_al5', 'rf5_v_al5', 'rf.rapa5_v_al5')
sub_data <- data[which(data$Comparison %in% comparisons),]
cl5 <- ggplot(data=sub_data, aes(y=NAME, x=factor(Comparison, levels = comparisons), size=-log10(FDR), color=NES)) + 
  geom_point() + 
  scale_color_gradient2(midpoint=0, low="blue", mid="white",
                        high="red", space ="Lab", limits=c(-3,3))+
  scale_size_continuous(range=c(1,6))+
  ggtitle('Cluster 5 GSEA') + theme_classic() + 
  theme(legend.position="right", axis.text.x = element_text(angle = 90)) + ylab('Gene Set') + xlab('Comparison')
cl5


#pdf('Fig5F.pdf',width=4, height=4)
#cl5
#dev.off()

comparisons <- c('f2_v_al2', 'rf2_v_al2', 'rf.rapa2_v_al2')
sub_data <- data[which(data$Comparison %in% comparisons),]
cl2 <- ggplot(data=sub_data, aes(y=NAME, x=factor(Comparison, levels = comparisons), size=-log10(FDR), color=NES)) + 
  geom_point() + 
  scale_color_gradient2(midpoint=0, low="blue", mid="white",
                        high="red", space ="Lab", limits=c(-3,3))+
  scale_size_continuous(range=c(1,6))+
  ggtitle('Cluster 2 GSEA') + theme_classic() + 
  theme(legend.position="right", axis.text.x = element_text(angle = 90)) + ylab('Gene Set') + xlab('Comparison')
cl2


#pdf('FigS3Da.pdf',width=4, height=4)
#cl2
#dev.off()

comparisons <- c('f10_v_al10', 'rf10_v_al10', 'rf.rapa10_v_al10')
sub_data <- data[which(data$Comparison %in% comparisons),]
cl10 <- ggplot(data=sub_data, aes(y=NAME, x=factor(Comparison, levels = comparisons), size=-log10(FDR), color=NES)) + 
  geom_point() + 
  scale_color_gradient2(midpoint=0, low="blue", mid="white",
                        high="red", space ="Lab", limits=c(-3,3))+
  scale_size_continuous(range=c(1,6))+
  ggtitle('Cluster 10 GSEA') + theme_classic() + 
  theme(legend.position="right", axis.text.x = element_text(angle = 90)) + ylab('Gene Set') + xlab('Comparison')
cl10


#pdf('FigS3Db.pdf',width=4, height=4)
#cl10
#dev.off()

#there is a glitch in this plot, cl2 loses x axis, legend order is different

figS3D <- ggarrange(cl2,cl10, ncol=2, nrow=1)
figS3D


#pdf('FigS3D_incorrect.pdf',width=8, height=4)
#figS3D
#dev.off()

Extended data Figure S4A - Feature Plots - color blind safe

DefaultAssay(integrated)<-"RNA"
colorScheme <- c("#C1BEBF","#fe6100")

fp.Muc2 <- FeaturePlot(integrated,reduction="umap",features="Muc2",cols=colorScheme, slot = "data",label=TRUE, repel=TRUE,label.size=4)
fp.Muc2


fp.Tff3 <- FeaturePlot(integrated,reduction="umap",features="Tff3",cols=colorScheme, slot = "data",label=TRUE, repel=TRUE,label.size=4)
fp.Tff3


fp.Lyz1 <- FeaturePlot(integrated,reduction="umap",features="Lyz1",cols=colorScheme, slot = "data",label=TRUE, repel=TRUE,label.size=4)
fp.Lyz1


fp.Defa30 <- FeaturePlot(integrated,reduction="umap",features="Defa30",cols=colorScheme, slot = "data",label=TRUE, repel=TRUE,label.size=4)
fp.Defa30


fp.Chga <- FeaturePlot(integrated,reduction="umap",features="Chga",cols=colorScheme, slot = "data",label=TRUE, repel=TRUE,label.size=4)
fp.Chga


fp.Reg3a <- FeaturePlot(integrated,reduction="umap",features="Reg3a",cols=colorScheme, slot = "data",label=TRUE, repel=TRUE,label.size=4)
fp.Reg3a


fp.Alpi <- FeaturePlot(integrated,reduction="umap",features="Alpi",cols=colorScheme, slot = "data",label=TRUE, repel=TRUE,label.size=4)
fp.Alpi


fp.Atoh1 <- FeaturePlot(integrated,reduction="umap",features="Atoh1",cols=colorScheme, slot = "data",label=TRUE, repel=TRUE,label.size=4)
fp.Atoh1


fp.Lgr5 <- FeaturePlot(integrated,reduction="umap",features="Lgr5",cols=colorScheme, slot = "data",label=TRUE, repel=TRUE,label.size=4)
fp.Lgr5


fp.Smoc2 <- FeaturePlot(integrated,reduction="umap",features="Smoc2",cols=colorScheme, slot = "data",label=TRUE, repel=TRUE,label.size=4)
fp.Smoc2

figS4A <- ggarrange(fp.Muc2,fp.Tff3,fp.Lyz1,fp.Defa30,fp.Chga,fp.Reg3a,fp.Alpi,fp.Atoh1,fp.Lgr5,fp.Smoc2, legend = "right", ncol = 5, nrow = 2)

figS4A


#pdf('FigS4A_cbSafe.pdf',width=20, height=10)
#figS4A
#dev.off()

Figure 5E - cell cycle data - color blind safe

DefaultAssay(integrated)<-"RNA"
gene.names <- rownames(integrated@assays$RNA@data)
Idents(object = integrated) <- integrated$seurat_clusters
stem.subset <- subset(integrated, idents = c("2","5","10"))
levels(stem.subset) <- c("5","2","10")

vln_colors <- c("2"="#117733",
                "5"="#999933",
                "10"="#009E73")
  
s.InData <- intersect(gene.names,GOI.lists$mm.s)
g2m.InData <- intersect(gene.names,GOI.lists$mm.g2m)
stem.subset[["percent.mm.s"]] <- PercentageFeatureSet(stem.subset, features = s.InData)
stem.subset[["percent.mm.g2m"]] <- PercentageFeatureSet(stem.subset, features = g2m.InData)
mm.s <- VlnPlot(stem.subset, cols = vln_colors, features="percent.mm.s",pt.size = 0.3,slot = "data")
mm.s

mm.g2m <- VlnPlot(stem.subset, cols = vln_colors, features="percent.mm.g2m",pt.size = 0.3,slot = "data")
mm.g2m


figS4b <- ggarrange(mm.s,mm.g2m, legend = FALSE, ncol=2, nrow=1)
figS4b

pdf('figS4b_cbSafe.pdf',width=8, height=4)
figS4b
dev.off()
png 
  2 

integrated[["percent.mm.s"]] <- PercentageFeatureSet(integrated, features = s.InData)
integrated[["percent.mm.g2m"]] <- PercentageFeatureSet(integrated, features = g2m.InData)

mm.g2m.Flag <- if_else(integrated@meta.data$percent.mm.g2m >= 0.3, "Yes", "No")
integrated@meta.data$mm.g2m.Flag <- mm.g2m.Flag

p <- table(integrated$clust_treat,integrated$mm.g2m.Flag)
p.g2m.summary <- round(prop.table(p,2),3)

mm.s.Flag <- if_else(integrated@meta.data$percent.mm.s >= 0.2, "Yes", "No")
integrated@meta.data$mm.s.Flag <- mm.s.Flag

p <- table(integrated$clust_treat,integrated$mm.s.Flag)
p.s.summary <- round(prop.table(p,1),3)

escape ssGSEA - run ssGSEA to quantify expression of the BitonI gene set clusters

This code is no longer working due to R and package updates but resulting data is stored in the seurat object escape 1.0.0 is probably required but is no longer available. the version in this R image is 1.0.1 escape ssGSEA - run ssGSEA to quantify expression of the BitonI gene set clusters

egs <- GeneSet(GOI.lists$Biton_S1_ISC.I, setName="BitonI")
ES <- enrichIt(obj = integrated, gene.sets = egs, groups = 1000, cores = 4)
[1] "Using sets of 1000 cells. Running 19 times."
Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘gsva’ for signature ‘"matrix", "character"’

escape ssGSEA - run ssGSEA to quantify expression of the BitonII gene set clusters

# egs <- GeneSet(GOI.lists$Biton_S1_ISC.II, setName="BitonII")
# ES <- enrichIt(obj = integrated, gene.sets = egs, groups = 1000, cores = 4)
# integrated@meta.data$BitonII_ssGSEA <- ES$BitonII

escape ssGSEA - run ssGSEA to quantify expression of the BitonIII gene set clusters

# egs <- GeneSet(GOI.lists$Biton_S1_ISC.III, setName="BitonIII")
# ES <- enrichIt(obj = integrated, gene.sets = egs, groups = 1000, cores = 4)
# integrated@meta.data$BitonIII_ssGSEA <- ES$BitonIII

Extended data 5 plots - colorblind safe

Figure 5G - Biton 1 in cluster5 Figure 5G_II - Biton II in cluster2 Figure 5G_III - Biton III in cluster10 Figure 5H - Pdgfa in cluster5 Figure S3E - Gkn3 in cluster5*

Idents(object = integrated) <- integrated$seurat_clusters
clust5.subset <- subset(integrated, idents = c("5"))
Idents(object = clust5.subset) <- clust5.subset$treat_clust

vln_colors <- c("al5"="#e69f00",
                "f5"="#56b4f9",
                "rf5"="#117733",
                "rf.rapa5"="#d55e00")

plot.order <- c("al5","f5","rf5","rf.rapa5")
Idents(object = clust5.subset) <- factor(Idents(object = clust5.subset), levels = plot.order)
vln.BitonI.ssGSEA <- VlnPlot(clust5.subset, cols = vln_colors, features="BitonI_ssGSEA",slot = "data",pt.size = 0.4) + 
  stat_summary(fun = median, geom='point', size = 15, colour = "black", shape = 95) + NoLegend() + ylab("Enrichment Score") + ggtitle("Biton ISC-I_ssGSEA")

vln.BitonI.ssGSEA


#pdf('Fig5G.pdf',width=4, height=4)
#vln.BitonI.ssGSEA
#dev.off()

vln.Pdgfa <- VlnPlot(clust5.subset, cols = vln_colors, features = c("Pdgfa"), slot= "data",pt.size = 0.4) + NoLegend()
vln.Pdgfa

pdf('FigS4g_cbSafe.pdf',width=4, height=4)
vln.Pdgfa
dev.off()
png 
  2 

vln.Gkn3 <- VlnPlot(clust5.subset, cols = vln_colors, features = c("Gkn3"), slot= "data",pt.size = 0.4) + NoLegend()
vln.Gkn3

pdf('FigS4h_cbSafe.pdf',width=4, height=4)
vln.Gkn3
dev.off()
png 
  2 

clust2.subset <- subset(integrated, idents = c("2"))
Idents(object = clust2.subset) <- clust2.subset$treat_clust

vln_colors <- c("al2"="#e69f00",
                "f2"="#56b4f9",
                "rf2"="#117733",
                "rf.rapa2"="#d55e00")

plot.order <- c("al2","f2","rf2","rf.rapa2")
Idents(object = clust2.subset) <- factor(Idents(object = clust2.subset), levels = plot.order)
vln.BitonII.ssGSEA <- VlnPlot(clust2.subset, cols = vln_colors, features="BitonII_ssGSEA",slot = "data",pt.size = 0.4) + 
  stat_summary(fun = median, geom='point', size = 15, colour = "black", shape = 95) + NoLegend() + ylab("Enrichment Score") + ggtitle("Biton ISC-II_ssGSEA")
vln.BitonII.ssGSEA


#pdf('Fig5G_II.pdf',width=4, height=4)
#vln.BitonII.ssGSEA
#dev.off()

clust10.subset <- subset(integrated, idents = c("10"))
Idents(object = clust10.subset) <- clust10.subset$treat_clust

vln_colors <- c("al10"="#e69f00",
                "f10"="#56b4f9",
                "rf10"="#117733",
                "rf.rapa10"="#d55e00")

plot.order <- c("al10","f10","rf10","rf.rapa10")
Idents(object = clust10.subset) <- factor(Idents(object = clust10.subset), levels = plot.order)
vln.BitonIII.ssGSEA <- VlnPlot(clust10.subset, cols = vln_colors, features="BitonIII_ssGSEA",slot = "data",pt.size = 0.4) + 
  stat_summary(fun = median, geom='point', size = 15, colour = "black", shape = 95) + NoLegend() + ylab("Enrichment Score") + ggtitle("Biton ISC-III_ssGSEA")
vln.BitonIII.ssGSEA


#pdf('Fig5G_III.pdf',width=4, height=4)
#vln.BitonIII.ssGSEA
#dev.off()

Biton plots assembled

bitonPlot <- ggarrange(vln.BitonI.ssGSEA,vln.BitonII.ssGSEA,vln.BitonIII.ssGSEA,nrow=1,ncol=3)
bitonPlot 


#pdf('FigS4f_cbSafe.pdf',width=10, height=5)
#bitonPlot
#dev.off()

Fig 5H style plots for Oat

Figure 5H style plots for Oat, Oct, Ass Asl in cluster5

DefaultAssay(integrated)<-"RNA"
Idents(object = integrated) <- integrated$seurat_clusters
clust5.subset <- subset(integrated, idents = c("5"))
Idents(object = clust5.subset) <- clust5.subset$treat_clust
levels(clust5.subset) <- c("al5","f5","rf5","rf.rapa5")
clust5.subset$treat_clust <- factor(x = clust5.subset$treat_clust, levels = c("al5","f5","rf5","rf.rapa5"))
VlnPlot(clust5.subset, features = c("Oat"), split.by = "treat_clust", group.by = "treat_clust", slot= "data",pt.size = 0.5)
The default behaviour of split.by has changed.
Separate violin plots are now plotted side-by-side.
To restore the old behaviour of a single split violin,
set split.plot = TRUE.
      
This message will be shown once per session.

vln.Oat.5 <- VlnPlot(clust5.subset, features = c("Oat"), slot= "data",pt.size = 0.1)
vln.Oat.5


#pdf('Fig5H_Oat.5.pdf',width=4, height=4)
#vln.Oat.5
#dev.off()

clust2.subset <- subset(integrated, idents = c("2"))
Idents(object = clust2.subset) <- clust2.subset$treat_clust
levels(clust2.subset) <- c("al2","f2","rf2","rf.rapa2")
clust2.subset$treat_clust <- factor(x = clust2.subset$treat_clust, levels = c("al2","f2","rf2","rf.rapa2"))
VlnPlot(clust2.subset, features = c("Oat"), split.by = "treat_clust", group.by = "treat_clust", slot= "data",pt.size = 0.5)


vln.Oat.2 <- VlnPlot(clust2.subset, features = c("Oat"), slot= "data",pt.size = 0.1)
vln.Oat.2


#pdf('Fig5H_Oat.2.pdf',width=4, height=4)
#vln.Oat.2
#dev.off()

clust10.subset <- subset(integrated, idents = c("10"))
Idents(object = clust10.subset) <- clust10.subset$treat_clust
levels(clust10.subset) <- c("al10","f10","rf10","rf.rapa10")
clust10.subset$treat_clust <- factor(x = clust10.subset$treat_clust, levels = c("al10","f10","rf10","rf.rapa10"))
VlnPlot(clust10.subset, features = c("Oat"), split.by = "treat_clust", group.by = "treat_clust", slot= "data",pt.size = 0.5)


#vln.Oat.10 <- VlnPlot(clust10.subset, features = c("Oat"), slot= "data",pt.size = 0.1)
#vln.Oat.10

#pdf('Fig5H_Oat.10.pdf',width=4, height=4)
#vln.Oat.10
#dev.off()

DefaultAssay(integrated)<-"RNA"
Idents(object = integrated) <- integrated$seurat_clusters
clust5.2.10.subset <- subset(integrated, idents = c("5","2","10"))
Idents(object = clust5.2.10.subset) <- clust5.2.10.subset$treat_clust
levels(clust5.2.10.subset) <- c("al5","f5","rf5","rf.rapa5","al2","f2","rf2","rf.rapa2","al10","f10","rf10","rf.rapa10")
clust5.2.10.subset$treat_clust <- factor(x = clust5.2.10.subset$treat_clust, levels = c("al5","f5","rf5","rf.rapa5","al2","f2","rf2","rf.rapa2","al10","f10","rf10","rf.rapa10"))
VlnPlot(clust5.2.10.subset, features = c("Oat"), split.by = "treat_clust", group.by = "treat_clust", slot= "data",pt.size = 0.5)


vln.Oat.5.2.10 <- VlnPlot(clust5.2.10.subset, features = c("Oat"), slot= "data",pt.size = 0.1)
vln.Oat.5.2.10


#pdf('Fig5H_Oat.5.2.10.pdf',width=12, height=4)
#vln.Oat.5.2.10
#dev.off()

Figure 5H style plots but without cluster for Oat*

DefaultAssay(integrated)<-"RNA"
Idents(object = integrated) <- integrated$orig.ident
levels(integrated) <- c("al","f","rf","rf.rapa")
integrated$orig.ident <- factor(x = integrated$orig.ident, levels = c("al","f","rf","rf.rapa"))
VlnPlot(integrated, features = c("Oat"), split.by = "orig.ident", group.by = "orig.ident", slot= "data",pt.size = 0.5)


vln.Oat.noclust <- VlnPlot(integrated, features = c("Oat"), slot= "data",pt.size = 0.1)
vln.Oat.noclust


#pdf('Fig5H_Oat.noclust.pdf',width=4, height=4)
#vln.Oat.noclust
#dev.off()

Figure S3E - Differential Expression Testing to prepare .rnk files*

# DefaultAssay(integrated)<-"RNA"
# Idents(object = integrated) <- integrated$treat_clust
# levels(x = integrated)
# ##
# #adjust the id1 and id2 variables to set up different tests
# #could use a loop for this
# ##
# id1 <- "al5"
# id2 <- "al2"
# outData <- paste(id1,id2,"Markers",sep=".")
# outData <- FindMarkers(integrated, ident.1 = id1, ident.2 = id2,logfc.threshold = 0, assay="RNA")
# outData <- tibble::rownames_to_column(outData,"#MGISym")
# rnk.tmp <- outData %>% dplyr::select(c("#MGISym","avg_logFC"))
# #write.table(rnk.tmp, sep='\t',file=paste0(id1,"_v_",id2,".rnk"),col.names=TRUE, quote=FALSE, row.names=FALSE)
# 
# id1 <- "al10"
# id2 <- "al2"
# outData <- paste(id1,id2,"Markers",sep=".")
# outData <- FindMarkers(integrated, ident.1 = id1, ident.2 = id2,logfc.threshold = 0, assay="RNA")
# outData <- tibble::rownames_to_column(outData,"#MGISym")
# rnk.tmp <- outData %>% dplyr::select(c("#MGISym","avg_logFC"))
# #write.table(rnk.tmp, sep='\t',file=paste0(id1,"_v_",id2,".rnk"),col.names=TRUE, quote=FALSE, row.names=FALSE)
# 
# id1 <- "al10"
# id2 <- "al5"
# outData <- paste(id1,id2,"Markers",sep=".")
# outData <- FindMarkers(integrated, ident.1 = id1, ident.2 = id2,logfc.threshold = 0, assay="RNA")
# outData <- tibble::rownames_to_column(outData,"#MGISym")
# rnk.tmp <- outData %>% dplyr::select(c("#MGISym","avg_logFC"))
# #write.table(rnk.tmp, sep='\t',file=paste0(id1,"_v_",id2,".rnk"),col.names=TRUE, quote=FALSE, row.names=FALSE)

Save integrated object with ssGSEA data

#save(integrated, file="integrated_final.Robj")
sessionInfo()
R version 4.0.3 (2020-10-10)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 20.04.5 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/liblapack.so.3

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8    LC_PAPER=en_US.UTF-8      
 [8] LC_NAME=C                  LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
 [1] grid      parallel  stats4    stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] ComplexHeatmap_2.6.2        scater_1.18.6               SingleCellExperiment_1.12.0 GSEABase_1.52.1             graph_1.68.0                annotate_1.68.0            
 [7] XML_3.99-0.5                AnnotationDbi_1.52.0        dittoSeq_1.2.6              escape_1.0.1                DESeq2_1.30.1               SummarizedExperiment_1.20.0
[13] Biobase_2.50.0              MatrixGenerics_1.2.1        matrixStats_0.58.0          GenomicRanges_1.42.0        GenomeInfoDb_1.26.7         IRanges_2.24.1             
[19] S4Vectors_0.28.1            BiocGenerics_0.36.1         kableExtra_1.3.1            knitr_1.31                  sctransform_0.3.2           ggpubr_0.4.0               
[25] ggrepel_0.9.1               ggplot2_3.3.3               openxlsx_4.2.3              readxl_1.3.1                Matrix_1.2-18               dplyr_1.0.4                
[31] umap_0.2.7.0                cowplot_1.1.1               Seurat_3.2.3               

loaded via a namespace (and not attached):
  [1] reticulate_1.18           tidyselect_1.1.0          RSQLite_2.2.3             htmlwidgets_1.5.3         BiocParallel_1.24.1       Rtsne_0.15                munsell_0.5.0            
  [8] codetools_0.2-16          ica_1.0-2                 future_1.21.0             miniUI_0.1.1.1            withr_3.0.0               colorspace_2.0-0          rstudioapi_0.13          
 [15] ROCR_1.0-11               ggsignif_0.6.0            tensor_1.5                listenv_0.8.0             labeling_0.4.2            GenomeInfoDbData_1.2.4    polyclip_1.10-0          
 [22] farver_2.0.3              pheatmap_1.0.12           bit64_4.0.5               parallelly_1.23.0         vctrs_0.6.5               generics_0.1.0            xfun_0.21                
 [29] R6_2.5.1                  clue_0.3-58               ggbeeswarm_0.6.0          rsvd_1.0.3                msigdbr_7.2.1             locfit_1.5-9.4            bitops_1.0-6             
 [36] spatstat.utils_2.0-0      cachem_1.0.3              DelayedArray_0.16.3       assertthat_0.2.1          promises_1.1.1            scales_1.1.1              beeswarm_0.2.3           
 [43] gtable_0.3.0              beachmat_2.6.4            Cairo_1.5-12.2            globals_0.14.0            goftest_1.2-2             rlang_1.1.4               genefilter_1.72.1        
 [50] GlobalOptions_0.1.2       splines_4.0.3             rstatix_0.6.0             lazyeval_0.2.2            broom_0.7.4               yaml_2.2.1                reshape2_1.4.4           
 [57] abind_1.4-5               backports_1.2.1           httpuv_1.5.5              tools_4.0.3               ellipsis_0.3.2            RColorBrewer_1.1-2        ggridges_0.5.3           
 [64] Rcpp_1.0.6                plyr_1.8.6                sparseMatrixStats_1.2.1   zlibbioc_1.36.0           purrr_1.0.2               RCurl_1.98-1.2            rpart_4.1-15             
 [71] openssl_2.2.0             deldir_0.2-9              GetoptLong_1.0.5          viridis_0.5.1             pbapply_1.4-3             zoo_1.8-8                 haven_2.3.1              
 [78] cluster_2.1.0             magrittr_2.0.3            data.table_1.13.6         RSpectra_0.16-0           scattermore_0.7           circlize_0.4.12           lmtest_0.9-38            
 [85] RANN_2.6.1                fitdistrplus_1.1-3        GSVA_1.38.2               hms_1.0.0                 patchwork_1.1.1           mime_0.9                  evaluate_0.24.0          
 [92] xtable_1.8-4              rio_0.5.16                shape_1.4.5               gridExtra_2.3             compiler_4.0.3            tibble_3.0.6              KernSmooth_2.23-17       
 [99] crayon_1.4.1              htmltools_0.5.8.1         mgcv_1.8-33               later_1.1.0.1             tidyr_1.1.2               geneplotter_1.68.0        DBI_1.1.1                
[106] MASS_7.3-53               car_3.0-10                cli_3.6.3                 igraph_1.2.6              forcats_0.5.1             pkgconfig_2.0.3           foreign_0.8-80           
[113] scuttle_1.0.4             plotly_4.9.3              xml2_1.3.2                vipor_0.4.5               webshot_0.5.2             XVector_0.30.0            rvest_0.3.6              
[120] stringr_1.4.0             digest_0.6.36             RcppAnnoy_0.0.18          spatstat.data_2.0-0       rmarkdown_2.6             cellranger_1.1.0          leiden_0.3.7             
[127] edgeR_3.32.1              uwot_0.1.10               DelayedMatrixStats_1.12.3 curl_5.2.1                shiny_1.6.0               rjson_0.2.20              lifecycle_1.0.4          
[134] nlme_3.1-149              jsonlite_1.8.8            BiocNeighbors_1.8.2       carData_3.0-4             limma_3.46.0              viridisLite_0.3.0         askpass_1.1              
[141] pillar_1.4.7              lattice_0.20-41           fastmap_1.2.0             httr_1.4.2                survival_3.2-7            glue_1.4.2                zip_2.1.1                
[148] spatstat_1.64-1           png_0.1-7                 bit_4.0.4                 stringi_1.5.3             blob_1.2.1                BiocSingular_1.6.0        memoise_2.0.1            
[155] irlba_2.3.3               future.apply_1.7.0       
writeLines(capture.output(sessionInfo()), "2024_sessionInfo.txt")
LS0tCnRpdGxlOiAiMjAyMSBGYXN0aW5nIENhbmNlciBQcm9qZWN0IgphdXRob3I6ICJDaGFybGllIFdoaXR0YWtlciIKZGF0ZTogIjEvMTkvMjAyMSAtIHJldmlzZWQgSnVseSAyMDI0IgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6IGRlZmF1bHQKICBodG1sX25vdGVib29rOiBkZWZhdWx0Ci0tLQojIyBTZXQgb3B0aW9ucyBhbmQgd29ya2luZyBkaXJlY3RvcnkKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKIyMgTG9hZCBsaWJyYXJpZXMKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLGVycm9yPUZBTFNFLG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkodW1hcCkKbGlicmFyeShkcGx5cikKbGlicmFyeShNYXRyaXgpCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KG9wZW54bHN4KQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ2dyZXBlbCkKbGlicmFyeShnZ3B1YnIpCmxpYnJhcnkoc2N0cmFuc2Zvcm0pCmxpYnJhcnkoa25pdHIpCmxpYnJhcnkoa2FibGVFeHRyYSkKI2xpYnJhcnkoYmlvbWFSdCkKbGlicmFyeShERVNlcTIpCmxpYnJhcnkoZXNjYXBlKQpsaWJyYXJ5KGRpdHRvU2VxKQpsaWJyYXJ5KEdTRUFCYXNlKQpsaWJyYXJ5KHNjYXRlcikKbGlicmFyeShDb21wbGV4SGVhdG1hcCkKYGBgCgojIyBJbXBvcnQgbWFya2VyIHNldHMKCmBgYHtyfQpnZW5lLmxpc3RzIDwtIHJlYWRfeGxzeCgiTXVub3pfWWlsbWF6X0NlbGxDeWNsZV9zaWduYXR1cmVzLnhsc3giKQpnZW5lLmxpc3RzLm5hbWVzIDwtIGNvbG5hbWVzKGdlbmUubGlzdHMpCkdPSS5saXN0cyA8LSBjKCkKZm9yIChpIGluIGdlbmUubGlzdHMubmFtZXMpIHsKICB0bXBMaXN0IDwtIGdlbmUubGlzdHMgJT4lIGRwbHlyOjpzZWxlY3QoYWxsX29mKGkpKQogIHRtcExpc3QgPC0gdG1wTGlzdFshaXMubmEodG1wTGlzdCldCiAgR09JLmxpc3RzW1tpXV0gPC0gdG1wTGlzdAp9CmBgYAoKIyBMb2FkIHRoZSBDZWxsIFJhbmdlciBNYXRyaXggRGF0YSBhbmQgY3JlYXRlIHRoZSBiYXNlIFNldXJhdCBvYmplY3QuKgoKdGhlIGluaXRpYWwgcHJvY2Vzc2luZyB3YXMgZG9uZSB3aXRoIHIgMy42LjEgd2l0aCBTZXVyYXQgMy4yLjAgLSB0aGUgVU1BUCBjb21lcyBvdXQgc2xpZ2h0bHkgZGlmZmVyZW50bHkgaW4gciA0LjAuMyB3aXRoIFNldXJhdCAzLjIuMyoKCmBgYHtyfQojYWwuZGF0IDwtIFJlYWQxMFgoIjIwMDIxOFlpbF9kYXRhL2FsL2ZpbHRlcmVkX2ZlYXR1cmVfYmNfbWF0cml4LyIpCiNmLmRhdCA8LSBSZWFkMTBYKCIyMDAyMThZaWxfZGF0YS9mL2ZpbHRlcmVkX2ZlYXR1cmVfYmNfbWF0cml4LyIpCiNyZi5kYXQgPC0gUmVhZDEwWCgiMjAwMjE4WWlsX2RhdGEvcmYvZmlsdGVyZWRfZmVhdHVyZV9iY19tYXRyaXgvIikKI3JmLnJhcGEuZGF0IDwtIFJlYWQxMFgoIjIwMDIxOFlpbF9kYXRhL3JmLnJhcGEvZmlsdGVyZWRfZmVhdHVyZV9iY19tYXRyaXgvIikKCiNhbCA8LSBDcmVhdGVTZXVyYXRPYmplY3QoY291bnRzID0gYWwuZGF0LCBwcm9qZWN0ID0gImFsIiwgbWluLmNlbGxzID0gMywgbWluLmZlYXR1cmVzID0gMjAwKQojZiA8LSBDcmVhdGVTZXVyYXRPYmplY3QoY291bnRzID0gZi5kYXQsIHByb2plY3QgPSAiZiIsIG1pbi5jZWxscyA9IDMsIG1pbi5mZWF0dXJlcyA9IDIwMCkKI3JmIDwtIENyZWF0ZVNldXJhdE9iamVjdChjb3VudHMgPSByZi5kYXQsIHByb2plY3QgPSAicmYiLCBtaW4uY2VsbHMgPSAzLCBtaW4uZmVhdHVyZXMgPSAyMDApCiNyZi5yYXBhIDwtIENyZWF0ZVNldXJhdE9iamVjdChjb3VudHMgPSByZi5yYXBhLmRhdCwgcHJvamVjdCA9ICJyZi5yYXBhIiwgbWluLmNlbGxzID0gMywgbWluLmZlYXR1cmVzID0gMjAwKQoKI2FsW1sicGVyY2VudC5tdCJdXSA8LSBQZXJjZW50YWdlRmVhdHVyZVNldChhbCwgcGF0dGVybiA9ICJebXQtIikKI2ZbWyJwZXJjZW50Lm10Il1dIDwtIFBlcmNlbnRhZ2VGZWF0dXJlU2V0KGYsIHBhdHRlcm4gPSAiXm10LSIpCiNyZltbInBlcmNlbnQubXQiXV0gPC0gUGVyY2VudGFnZUZlYXR1cmVTZXQocmYsIHBhdHRlcm4gPSAiXm10LSIpCiNyZi5yYXBhW1sicGVyY2VudC5tdCJdXSA8LSBQZXJjZW50YWdlRmVhdHVyZVNldChyZi5yYXBhLCBwYXR0ZXJuID0gIl5tdC0iKQoKI1ZsblBsb3QoYWwsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiwgIm5Db3VudF9STkEiLCAicGVyY2VudC5tdCIpLCBuY29sID0gMykKI1ZsblBsb3QoZiwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIG5jb2wgPSAzKQojVmxuUGxvdChyZiwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIG5jb2wgPSAzKQojVmxuUGxvdChhbCwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIG5jb2wgPSAzKQpgYGAKCiMjIE1lcmdlIHNhbXBsZXMgdG8gc2luZ2xlIFNldXJhdCBPYmplY3QKCmBgYHtyfQojbWVyZ2VkX1NldSA8LSBtZXJnZShhbCwgYyhmLHJmLHJmLnJhcGEpLCBwcm9qZWN0ID0gIkRpZXQiKQoKI21lcmdlZF9TZXUgPC0gTm9ybWFsaXplRGF0YShtZXJnZWRfU2V1LCBub3JtYWxpemF0aW9uLm1ldGhvZCA9ICJMb2dOb3JtYWxpemUiLCBzY2FsZS5mYWN0b3IgPSAxMDAwMCkKI21lcmdlZF9TZXUgPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMobWVyZ2VkX1NldSwgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSAyMDAwKQojbWVyZ2VkX1NldSA8LSBTY2FsZURhdGEobWVyZ2VkX1NldSkKI21lcmdlZF9TZXUgPC0gUnVuUENBKG1lcmdlZF9TZXUsIGZlYXR1cmVzID0gVmFyaWFibGVGZWF0dXJlcyhvYmplY3QgPSBtZXJnZWRfU2V1KSkKI21lcmdlZF9TZXUgPC0gUnVuVU1BUChtZXJnZWRfU2V1LCByZWR1Y3Rpb249InBjYSIsZGltcz0xOjMwKQojbWVyZ2VkX1NldSA8LSBSdW5UU05FKG1lcmdlZF9TZXUsIHJlZHVjdGlvbj0icGNhIixkaW1zPTE6MzApCiNtZXJnZWRfU2V1IDwtIEZpbmROZWlnaGJvcnMobWVyZ2VkX1NldSwgZGltcyA9IDE6MzAsIHZlcmJvc2UgPSBGQUxTRSkKI21lcmdlZF9TZXUgPC0gRmluZENsdXN0ZXJzKG1lcmdlZF9TZXUsIHZlcmJvc2UgPSBGQUxTRSkKCiNEaW1QbG90KG1lcmdlZF9TZXUscmVkdWN0aW9uPSJ1bWFwIixncm91cC5ieT0ib3JpZy5pZGVudCIsbGFiZWw9VFJVRSxyZXBlbD1GQUxTRSkKCiNGZWF0dXJlUGxvdChtZXJnZWRfU2V1LHJlZHVjdGlvbj0idW1hcCIsZmVhdHVyZXM9Im10LUN5dGIiLG1pbi5jdXRvZmY9MCxtYXguY3V0b2ZmPTQsY29scz1jKCJncmV5IiwicmVkIikpCiNGZWF0dXJlUGxvdChtZXJnZWRfU2V1LHJlZHVjdGlvbj0idW1hcCIsZmVhdHVyZXM9InBlcmNlbnQubXQiLGNvbHM9YygiZ3JleSIsInJlZCIpKQojRmVhdHVyZVBsb3QobWVyZ2VkX1NldSxyZWR1Y3Rpb249InVtYXAiLGZlYXR1cmVzPSJuRmVhdHVyZV9STkEiLGNvbHM9YygiZ3JleSIsInJlZCIpKQpgYGAKCiMjIFNhdmUvTG9hZCBzZXVyYXQgb2JqZWN0CgpgYGB7cn0KI3NhdmUobWVyZ2VkX1NldSwgZmlsZT0ibWVyZ2VkLlJvYmoiKQojbG9hZCgibWVyZ2VkLlJvYmoiKQpgYGAKCiMjIERhdGFzZXQgSW50ZWdyYXRpb24gCgpgYGB7cn0KI2RpIDwtIFNwbGl0T2JqZWN0KG1lcmdlZF9TZXUsIHNwbGl0LmJ5ID0gIm9yaWcuaWRlbnQiKQoKI2ZvciAoaSBpbiAxOmxlbmd0aChkaSkpIHsKIyAgZGlbW2ldXSA8LSBOb3JtYWxpemVEYXRhKGRpW1tpXV0sIHZlcmJvc2UgPSBGQUxTRSkKIyAgZGlbW2ldXSA8LSBGaW5kVmFyaWFibGVGZWF0dXJlcyhkaVtbaV1dLCBzZWxlY3Rpb24ubWV0aG9kID0gInZzdCIsIG5mZWF0dXJlcyA9IDIwMDAsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBGQUxTRSkKI30KCiNkYXQuYW5jaG9ycyA8LSBGaW5kSW50ZWdyYXRpb25BbmNob3JzKG9iamVjdC5saXN0PWRpLGRpbXM9MTozMCkKI2ludGVncmF0ZWQgPC0gSW50ZWdyYXRlRGF0YShhbmNob3JzZXQ9ZGF0LmFuY2hvcnMsZGltPTE6MzApCgojRGVmYXVsdEFzc2F5KGludGVncmF0ZWQpPC0iaW50ZWdyYXRlZCIKI2ludGVncmF0ZWQgPC0gU2NhbGVEYXRhKGludGVncmF0ZWQpCiNpbnRlZ3JhdGVkIDwtIFJ1blBDQShpbnRlZ3JhdGVkLG5wY3M9MzApCiNpbnRlZ3JhdGVkIDwtIFJ1blVNQVAoaW50ZWdyYXRlZCxyZWR1Y3Rpb249InBjYSIsZGltcz0xOjMwKQojaW50ZWdyYXRlZCA8LSBSdW5UU05FKGludGVncmF0ZWQscmVkdWN0aW9uPSJwY2EiLGRpbXM9MTozMCkKI2ludGVncmF0ZWQgPC0gRmluZE5laWdoYm9ycyhpbnRlZ3JhdGVkLCBkaW1zID0gMTozMCwgdmVyYm9zZSA9IEZBTFNFKQojaW50ZWdyYXRlZCA8LSBGaW5kQ2x1c3RlcnMoaW50ZWdyYXRlZCwgdmVyYm9zZSA9IEZBTFNFKQpgYGAKCiMjIExvYWQgaW50ZWdyYXRlZCBkYXRhIGFuZCBjcmVhdGUgVU1BUCBmcm9tIG9yaWdpbmFsIGludGVncmF0ZWQgcnVuKgoKTk9URTogbG9hZGluZyBmaW5hbCBvYmplY3QgdG8gYXZvaWQgcmVjYWxjdWxhdGluZyBzc0dTRUEgZGF0YQoKYGBge3J9CiNsb2FkKCJpbnRlZ3JhdGVkX29yaWcuUm9iaiIpCmxvYWQoIi4uL3JlcG9fZGF0YS9pbnRlZ3JhdGVkXzA5MTEyMC5Sb2JqIikKI2xvYWQoIi4uL3JlcG9fZGF0YS9pbnRlZ3JhdGVkX2ZpbmFsLlJvYmoiKQpgYGAKCiMjIFRlc3QgcGxvdHMKCmBgYHtyfQpEZWZhdWx0QXNzYXkoaW50ZWdyYXRlZCk8LSJpbnRlZ3JhdGVkIgpEaW1QbG90KGludGVncmF0ZWQscmVkdWN0aW9uPSJ1bWFwIixzcGxpdC5ieT0ib3JpZy5pZGVudCIsZ3JvdXAuYnk9Im9yaWcuaWRlbnQiKQpEaW1QbG90KGludGVncmF0ZWQscmVkdWN0aW9uPSJ1bWFwIixncm91cC5ieT0ib3JpZy5pZGVudCIpCkRpbVBsb3QoaW50ZWdyYXRlZCxyZWR1Y3Rpb249InVtYXAiLGdyb3VwLmJ5PSJpbnRlZ3JhdGVkX3Nubl9yZXMuMC44IiwgbGFiZWw9VFJVRSkKYGBgCgojIEZpZ3VyZSAzQiAtIEFkZCBjbHVzdGVyL3RyZWF0bWVudCBtZXRhZGF0YSBjb2x1bW5zIGFuZCBwbG90IGxhYmVsZWQgVU1BUAoKYGBge3IsIGZpZy53aWR0aD0xNCwgZmlnLmhlaWdodD0xMH0KaW50ZWdyYXRlZEBtZXRhLmRhdGEkdHJlYXRfY2x1c3QgPC0gcGFzdGUwKGludGVncmF0ZWRAbWV0YS5kYXRhJG9yaWcuaWRlbnQsaW50ZWdyYXRlZEBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjAuOCkKaW50ZWdyYXRlZEBtZXRhLmRhdGEkY2x1c3RfdHJlYXQgPC0gcGFzdGUwKGludGVncmF0ZWRAbWV0YS5kYXRhJGludGVncmF0ZWRfc25uX3Jlcy4wLjgsaW50ZWdyYXRlZEBtZXRhLmRhdGEkb3JpZy5pZGVudCkKaW50ZWdyYXRlZEBtZXRhLmRhdGEkY2VsbHR5cGUgPC0gaW50ZWdyYXRlZEBtZXRhLmRhdGEkaW50ZWdyYXRlZF9zbm5fcmVzLjAuOApJZGVudHMob2JqZWN0ID0gaW50ZWdyYXRlZCkgPC0gaW50ZWdyYXRlZCRjZWxsdHlwZQoKaW50ZWdyYXRlZCA8LSBSZW5hbWVJZGVudHMob2JqZWN0ID0gaW50ZWdyYXRlZCwgICcxNicgPSAnMTZfVHVmdCcpCmludGVncmF0ZWQgPC0gUmVuYW1lSWRlbnRzKG9iamVjdCA9IGludGVncmF0ZWQsICAnMTEnID0gJzExX0VDJykKaW50ZWdyYXRlZCA8LSBSZW5hbWVJZGVudHMob2JqZWN0ID0gaW50ZWdyYXRlZCwgICcxMycgPSAnMTNfRUVDJykKaW50ZWdyYXRlZCA8LSBSZW5hbWVJZGVudHMob2JqZWN0ID0gaW50ZWdyYXRlZCwgICcyJyA9ICcyX1N0ZW0nKQppbnRlZ3JhdGVkIDwtIFJlbmFtZUlkZW50cyhvYmplY3QgPSBpbnRlZ3JhdGVkLCAgJzUnID0gJzVfU3RlbScpCmludGVncmF0ZWQgPC0gUmVuYW1lSWRlbnRzKG9iamVjdCA9IGludGVncmF0ZWQsICAnMTAnID0gJzEwX1N0ZW0nKQppbnRlZ3JhdGVkIDwtIFJlbmFtZUlkZW50cyhvYmplY3QgPSBpbnRlZ3JhdGVkLCAgJzE0JyA9ICcxNF9QYW5ldGgnKQppbnRlZ3JhdGVkIDwtIFJlbmFtZUlkZW50cyhvYmplY3QgPSBpbnRlZ3JhdGVkLCAgJzgnID0gJzhfU2VjcmV0b3J5X1Byb2dlbml0b3InKQppbnRlZ3JhdGVkIDwtIFJlbmFtZUlkZW50cyhvYmplY3QgPSBpbnRlZ3JhdGVkLCAgJzknID0gJzlfR29ibGV0JykKaW50ZWdyYXRlZCA8LSBSZW5hbWVJZGVudHMob2JqZWN0ID0gaW50ZWdyYXRlZCwgICcxJyA9ICcxX1NlY3JldG9yeV9Qcm9nZW5pdG9yJykKaW50ZWdyYXRlZCA8LSBSZW5hbWVJZGVudHMob2JqZWN0ID0gaW50ZWdyYXRlZCwgICc0JyA9ICc0X1NlY3JldG9yeV9Qcm9nZW5pdG9yJykKaW50ZWdyYXRlZCA8LSBSZW5hbWVJZGVudHMob2JqZWN0ID0gaW50ZWdyYXRlZCwgICcxNScgPSAnMTVfU2VjcmV0b3J5X1Byb2dlbml0b3InKQppbnRlZ3JhdGVkIDwtIFJlbmFtZUlkZW50cyhvYmplY3QgPSBpbnRlZ3JhdGVkLCAgJzMnID0gJzNfRUNfUHJvZ2VuaXRvcicpCmludGVncmF0ZWQgPC0gUmVuYW1lSWRlbnRzKG9iamVjdCA9IGludGVncmF0ZWQsICAnNicgPSAnNl9FQ19Qcm9nZW5pdG9yJykKaW50ZWdyYXRlZCA8LSBSZW5hbWVJZGVudHMob2JqZWN0ID0gaW50ZWdyYXRlZCwgICcwJyA9ICcwX0Vhcmx5X1RBJykKaW50ZWdyYXRlZCA8LSBSZW5hbWVJZGVudHMob2JqZWN0ID0gaW50ZWdyYXRlZCwgICc3JyA9ICc3X0Vhcmx5X1RBJykKaW50ZWdyYXRlZCA8LSBSZW5hbWVJZGVudHMob2JqZWN0ID0gaW50ZWdyYXRlZCwgICcxMicgPSAnMTJfVW5rbm93bicpCgoKaW50ZWdyYXRlZFtbImNsdXN0X2NlbGx0eXBlIl1dIDwtIElkZW50cyhvYmplY3QgPSBpbnRlZ3JhdGVkKQpgYGAKCiMjIEZpZzNiIFVNQVAgUGxvdCB3aXRoIGNvbG9yIGJsaW5kIHNhZmUgY29sb3JzCgpgYGB7ciwgZmlnLndpZHRoPTE0LCBmaWcuaGVpZ2h0PTEwfQpJZGVudHMob2JqZWN0ID0gaW50ZWdyYXRlZCkgPC0gaW50ZWdyYXRlZCRjbHVzdF9jZWxsdHlwZQoKY2VsbHR5cGVfY29sb3JzIDwtIGMoIjJfU3RlbSI9IiMxMTc3MzMiLAogICAgICAgICAgICAgICAgICAgICAiNV9TdGVtIj0iIzk5OTkzMyIsCiAgICAgICAgICAgICAgICAgICAgICIxMF9TdGVtIj0iIzAwOUU3MyIsCiAgICAgICAgICAgICAgICAgICAgICIwX0Vhcmx5X1RBIj0iI0U2OUYwMCIsCiAgICAgICAgICAgICAgICAgICAgICI3X0Vhcmx5X1RBIj0iI0Q1NUUwMCIsCiAgICAgICAgICAgICAgICAgICAgICI2X0VDX1Byb2dlbml0b3IiPSIjMDA3MkIyIiwKICAgICAgICAgICAgICAgICAgICAgIjNfRUNfUHJvZ2VuaXRvciI9IiM1NkI0RTkiLAogICAgICAgICAgICAgICAgICAgICAiMTFfRUMiPSIjODhDQ0VFIiwKICAgICAgICAgICAgICAgICAgICAgIjEzX0VFQyI9IiM2Njk5Q0MiLAogICAgICAgICAgICAgICAgICAgICAiMV9TZWNyZXRvcnlfUHJvZ2VuaXRvciI9IiM2NjExMDAiLAogICAgICAgICAgICAgICAgICAgICAiNF9TZWNyZXRvcnlfUHJvZ2VuaXRvciI9IiM4ODIyNTUiLAogICAgICAgICAgICAgICAgICAgICAiOF9TZWNyZXRvcnlfUHJvZ2VuaXRvciI9IiNDQzY2NzciLAogICAgICAgICAgICAgICAgICAgICAiMTVfU2VjcmV0b3J5X1Byb2dlbml0b3IiPSIjQUE0NDk5IiwKICAgICAgICAgICAgICAgICAgICAgIjE0X1BhbmV0aCI9IiMzMzIyODgiLAogICAgICAgICAgICAgICAgICAgICAiMTZfVHVmdCI9IiMwMDAwMDAiLAogICAgICAgICAgICAgICAgICAgICAiOV9Hb2JsZXQiPSIjRjBFNDQyIiwKICAgICAgICAgICAgICAgICAgICAgIjEyX1Vua25vd24iPSIjOTk5OTk5IikgIAoKZHAuY2IgPC0gRGltUGxvdChpbnRlZ3JhdGVkLHJlZHVjdGlvbj0idW1hcCIsIGNvbHM9Y2VsbHR5cGVfY29sb3JzLCBsYWJlbD1UUlVFLCByZXBlbD1UUlVFLCBwdC5zaXplPTIsIGxhYmVsLnNpemU9NikgKyBOb0xlZ2VuZCgpCmRwLmNiCgojcGRmKCdGaWczYi5jYlNhZmUucGRmJyx3aWR0aD0xNCwgaGVpZ2h0PTEwKQojZHAuY2IKI2Rldi5vZmYoKQpgYGAKCiMjIEZpZ3VyZSAzQyAtIExHUjUgVmxuIHBsb3Qgd2l0aCBjb2xvciBibGluZCBzYWZlIGNvbG9ycwoKYGBge3IsIGZpZy53aWR0aD0xNCwgZmlnLmhlaWdodD04fQpEZWZhdWx0QXNzYXkoaW50ZWdyYXRlZCk8LSJSTkEiCklkZW50cyhvYmplY3QgPSBpbnRlZ3JhdGVkKSA8LSBpbnRlZ3JhdGVkJGludGVncmF0ZWRfc25uX3Jlcy4wLjgKcGxvdE9yZGVyIDwtIGMoIjUiLCIyIiwiMTAiLCIwIiwiMSIsIjMiLCI0IiwiNiIsIjciLCI4IiwiOSIsIjExIiwiMTIiLCIxMyIsIjE0IiwiMTUiLCIxNiIpCgp2bG5fY29sb3JzIDwtIGMoIjIiPSIjMTE3NzMzIiwKICAgICAgICAgICAgICAgICI1Ij0iIzk5OTkzMyIsCiAgICAgICAgICAgICAgICAiMTAiPSIjMDA5RTczIiwKICAgICAgICAgICAgICAgICIwIj0iI0U2OUYwMCIsCiAgICAgICAgICAgICAgICAiMSI9IiM2NjExMDAiLAogICAgICAgICAgICAgICAgIjMiPSIjNTZCNEU5IiwKICAgICAgICAgICAgICAgICI0Ij0iIzg4MjI1NSIsCiAgICAgICAgICAgICAgICAiNiI9IiMwMDcyQjIiLAogICAgICAgICAgICAgICAgIjciPSIjRDU1RTAwIiwKICAgICAgICAgICAgICAgICI4Ij0iI0NDNjY3NyIsCiAgICAgICAgICAgICAgICAiOSI9IiNGMEU0NDIiLAogICAgICAgICAgICAgICAgIjExIj0iIzg4Q0NFRSIsCiAgICAgICAgICAgICAgICAiMTIiPSIjOTk5OTk5IiwKICAgICAgICAgICAgICAgICIxMyI9IiM2Njk5Q0MiLAogICAgICAgICAgICAgICAgIjE0Ij0iIzMzMjI4OCIsCiAgICAgICAgICAgICAgICAiMTUiPSIjQUE0NDk5IiwKICAgICAgICAgICAgICAgICIxNiI9IiMwMDAwMDAiKSAgCgpJZGVudHMoaW50ZWdyYXRlZCkgPC0gZmFjdG9yKElkZW50cyhpbnRlZ3JhdGVkKSwgbGV2ZWxzPSBwbG90T3JkZXIpCnZsLmNiIDwtIFZsblBsb3QoaW50ZWdyYXRlZCwgY29scz12bG5fY29sb3JzLCBpZGVudHMgPSAsIGZlYXR1cmVzID0gYygiTGdyNSIpLCBwdC5zaXplID0gMC41LCBzbG90PSJkYXRhIikKdmwuY2IKCiNwZGYoJ0ZpZzNjX2NiU2FmZS5wZGYnLHdpZHRoPTE0LCBoZWlnaHQ9OCkKI3ZsLmNiCiNkZXYub2ZmKCkKYGBgCgojIyBGaWd1cmUgUzMsQiAtIFRhYmxlIG9mIGNlbGwgY291bnRzIGluIGVhY2ggaW50ZWdyYXRlZCBkYXRhIGNsdXN0ZXIgYW5kIHNhbXBsZQoKYGBge3J9CnAuaW50ZWdyYXRlZCA8LSB0YWJsZShpbnRlZ3JhdGVkQG1ldGEuZGF0YSRpbnRlZ3JhdGVkX3Nubl9yZXMuMC44LGludGVncmF0ZWRAbWV0YS5kYXRhJG9yaWcuaWRlbnQpCnJvdW5kKHByb3AudGFibGUocC5pbnRlZ3JhdGVkLDIpLDMpCmBgYAoKIyMgRmlndXJlIDVEIC0gaGVhdG1hcAoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0xMH0KRGVmYXVsdEFzc2F5KGludGVncmF0ZWQpPC0gImludGVncmF0ZWQiCklkZW50cyhvYmplY3QgPSBpbnRlZ3JhdGVkKSA8LSBpbnRlZ3JhdGVkJGludGVncmF0ZWRfc25uX3Jlcy4wLjgKZGQgPC0gc3Vic2V0KGludGVncmF0ZWQsIGlkZW50cyA9IGMoIjIiLCAiNSIsICIxMCIpLCBkb3duc2FtcGxlPTEwMCkKCnRvcHZzdCA8LSBoZWFkKFZhcmlhYmxlRmVhdHVyZXMoZGQpLCA1MDApCm1hdCA8LSBhcy5tYXRyaXgoZGRAYXNzYXlzJGludGVncmF0ZWRAc2NhbGUuZGF0YSkgI2FzLm1hdHJpeChzdWJzZXRfZGRAYXNzYXlzJGludGVncmF0ZWRAc2NhbGUuZGF0YSkKbWF0IDwtIG1hdFt0b3B2c3QsXQoKZ2VuZXMgPC0gYyhHT0kubGlzdHMkQml0b25fUzFfSVNDLkksIEdPSS5saXN0cyRCaXRvbl9TMV9JU0MuSUksIEdPSS5saXN0cyRCaXRvbl9TMV9JU0MuSUlJKQpsYWJlbHMgPC0gYyhyZXAoJ0JpdG9uIElTQyBJJywgbGVuZ3RoKEdPSS5saXN0cyRCaXRvbl9TMV9JU0MuSSkpLCAKICAgICAgICAgICAgcmVwKCdCaXRvbiBJU0MgSUknLCBsZW5ndGgoR09JLmxpc3RzJEJpdG9uX1MxX0lTQy5JSSkpLCAKICAgICAgICAgICAgcmVwKCdCaXRvbiBJU0MgSUlJJywgbGVuZ3RoKEdPSS5saXN0cyRCaXRvbl9TMV9JU0MuSUlJKSkpCgppZHhzIDwtIHdoaWNoKGdlbmVzICVpbiUgcm93bmFtZXMobWF0KSkKZ2VuZXMgPC0gZ2VuZXNbaWR4c10KbGFiZWxzIDwtIGxhYmVsc1tpZHhzXQptYXQgPC0gbWF0W2dlbmVzLF0KCmh0IDwtIEhlYXRtYXAobWF0LCBjb2x1bW5fbmFtZXNfc2lkZSA9ICd0b3AnLCByb3dfbmFtZXNfZ3AgPSBncGFyKGZvbnRzaXplID0gOSksIGNvbHVtbl9uYW1lc19ncCA9IGdwYXIoZm9udHNpemUgPSAxMiksCiAgICAgICAgICAgICAgY29sdW1uX3RpdGxlID0gJycsIG5hbWUgPSAnc2NhbGVkIGRhdGEnLCBjb2x1bW5fbGFiZWxzID0gcmVwKCcnLCBuY29sKG1hdCkpLAogICAgICAgICAgICAgIGNvbHVtbl9zcGxpdCA9IGZhY3Rvcihhcy5jaGFyYWN0ZXIoZGQkaW50ZWdyYXRlZF9zbm5fcmVzLjAuOCksIGxldmVscyA9IGMoJzUnLCAnMicsICcxMCcpKSwgCiAgICAgICAgICAgICAgcm93X3NwbGl0ID0gbGFiZWxzLCByb3dfb3JkZXIgPSBnZW5lcywgI2NvbHVtbl9vcmRlciA9IHNvcnQoY29sbmFtZXMobWF0KSksCiAgICAgICAgICAgICAgY2x1c3Rlcl9jb2x1bW5fc2xpY2VzID0gRkFMU0UsCiAgICAgICAgICAgICAgdG9wX2Fubm90YXRpb24gPSBIZWF0bWFwQW5ub3RhdGlvbihjbHVzdGVyID0gYXMuY2hhcmFjdGVyKGRkJGludGVncmF0ZWRfc25uX3Jlcy4wLjgpKSkKCmRyYXcoaHQpCgojcGRmKCdGaWczRC5wZGYnLHdpZHRoPTEyLCBoZWlnaHQ9MTApCiNkcmF3KGh0KQojZGV2Lm9mZigpCmBgYAoKIyMgR1NFQSBkb3QgcGxvdHMKCmBgYHtyfQpkYXRhIDwtIGFzLmRhdGEuZnJhbWUocmVhZF9leGNlbCgnY2x1c3Rlcl8yXzVfMTBzdGVtX2dzZWEueGxzeCcsIHNoZWV0ID0gJ1NoZWV0MicpKQpkYXRhCmRhdGEkRkRSIDwtIGRhdGEkYEZEUiBxLXZhbGAgKyAwLjAwMQpkYXRhJENvbXBhcmlzb24gPC0gZ3N1YignXFwubm9OQVxcLk5FUycsJycsZGF0YSRDb21wYXJpc29uKQoKY29tcGFyaXNvbnMgPC0gYygnZjVfdl9hbDUnLCAncmY1X3ZfYWw1JywgJ3JmLnJhcGE1X3ZfYWw1JykKc3ViX2RhdGEgPC0gZGF0YVt3aGljaChkYXRhJENvbXBhcmlzb24gJWluJSBjb21wYXJpc29ucyksXQpjbDUgPC0gZ2dwbG90KGRhdGE9c3ViX2RhdGEsIGFlcyh5PU5BTUUsIHg9ZmFjdG9yKENvbXBhcmlzb24sIGxldmVscyA9IGNvbXBhcmlzb25zKSwgc2l6ZT0tbG9nMTAoRkRSKSwgY29sb3I9TkVTKSkgKyAKICBnZW9tX3BvaW50KCkgKyAKICBzY2FsZV9jb2xvcl9ncmFkaWVudDIobWlkcG9pbnQ9MCwgbG93PSJibHVlIiwgbWlkPSJ3aGl0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGhpZ2g9InJlZCIsIHNwYWNlID0iTGFiIiwgbGltaXRzPWMoLTMsMykpKwogIHNjYWxlX3NpemVfY29udGludW91cyhyYW5nZT1jKDEsNikpKwogIGdndGl0bGUoJ0NsdXN0ZXIgNSBHU0VBJykgKyB0aGVtZV9jbGFzc2ljKCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249InJpZ2h0IiwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsgeWxhYignR2VuZSBTZXQnKSArIHhsYWIoJ0NvbXBhcmlzb24nKQpjbDUKCiNwZGYoJ0ZpZzVGLnBkZicsd2lkdGg9NCwgaGVpZ2h0PTQpCiNjbDUKI2Rldi5vZmYoKQoKY29tcGFyaXNvbnMgPC0gYygnZjJfdl9hbDInLCAncmYyX3ZfYWwyJywgJ3JmLnJhcGEyX3ZfYWwyJykKc3ViX2RhdGEgPC0gZGF0YVt3aGljaChkYXRhJENvbXBhcmlzb24gJWluJSBjb21wYXJpc29ucyksXQpjbDIgPC0gZ2dwbG90KGRhdGE9c3ViX2RhdGEsIGFlcyh5PU5BTUUsIHg9ZmFjdG9yKENvbXBhcmlzb24sIGxldmVscyA9IGNvbXBhcmlzb25zKSwgc2l6ZT0tbG9nMTAoRkRSKSwgY29sb3I9TkVTKSkgKyAKICBnZW9tX3BvaW50KCkgKyAKICBzY2FsZV9jb2xvcl9ncmFkaWVudDIobWlkcG9pbnQ9MCwgbG93PSJibHVlIiwgbWlkPSJ3aGl0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGhpZ2g9InJlZCIsIHNwYWNlID0iTGFiIiwgbGltaXRzPWMoLTMsMykpKwogIHNjYWxlX3NpemVfY29udGludW91cyhyYW5nZT1jKDEsNikpKwogIGdndGl0bGUoJ0NsdXN0ZXIgMiBHU0VBJykgKyB0aGVtZV9jbGFzc2ljKCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249InJpZ2h0IiwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsgeWxhYignR2VuZSBTZXQnKSArIHhsYWIoJ0NvbXBhcmlzb24nKQpjbDIKCiNwZGYoJ0ZpZ1MzRGEucGRmJyx3aWR0aD00LCBoZWlnaHQ9NCkKI2NsMgojZGV2Lm9mZigpCgpjb21wYXJpc29ucyA8LSBjKCdmMTBfdl9hbDEwJywgJ3JmMTBfdl9hbDEwJywgJ3JmLnJhcGExMF92X2FsMTAnKQpzdWJfZGF0YSA8LSBkYXRhW3doaWNoKGRhdGEkQ29tcGFyaXNvbiAlaW4lIGNvbXBhcmlzb25zKSxdCmNsMTAgPC0gZ2dwbG90KGRhdGE9c3ViX2RhdGEsIGFlcyh5PU5BTUUsIHg9ZmFjdG9yKENvbXBhcmlzb24sIGxldmVscyA9IGNvbXBhcmlzb25zKSwgc2l6ZT0tbG9nMTAoRkRSKSwgY29sb3I9TkVTKSkgKyAKICBnZW9tX3BvaW50KCkgKyAKICBzY2FsZV9jb2xvcl9ncmFkaWVudDIobWlkcG9pbnQ9MCwgbG93PSJibHVlIiwgbWlkPSJ3aGl0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGhpZ2g9InJlZCIsIHNwYWNlID0iTGFiIiwgbGltaXRzPWMoLTMsMykpKwogIHNjYWxlX3NpemVfY29udGludW91cyhyYW5nZT1jKDEsNikpKwogIGdndGl0bGUoJ0NsdXN0ZXIgMTAgR1NFQScpICsgdGhlbWVfY2xhc3NpYygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJyaWdodCIsIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArIHlsYWIoJ0dlbmUgU2V0JykgKyB4bGFiKCdDb21wYXJpc29uJykKY2wxMAoKI3BkZignRmlnUzNEYi5wZGYnLHdpZHRoPTQsIGhlaWdodD00KQojY2wxMAojZGV2Lm9mZigpCgojdGhlcmUgaXMgYSBnbGl0Y2ggaW4gdGhpcyBwbG90LCBjbDIgbG9zZXMgeCBheGlzLCBsZWdlbmQgb3JkZXIgaXMgZGlmZmVyZW50CgpmaWdTM0QgPC0gZ2dhcnJhbmdlKGNsMixjbDEwLCBuY29sPTIsIG5yb3c9MSkKZmlnUzNECgojcGRmKCdGaWdTM0RfaW5jb3JyZWN0LnBkZicsd2lkdGg9OCwgaGVpZ2h0PTQpCiNmaWdTM0QKI2Rldi5vZmYoKQpgYGAKCiMjIEV4dGVuZGVkIGRhdGEgRmlndXJlIFM0QSAtIEZlYXR1cmUgUGxvdHMgLSBjb2xvciBibGluZCBzYWZlCgpgYGB7cn0KRGVmYXVsdEFzc2F5KGludGVncmF0ZWQpPC0iUk5BIgpjb2xvclNjaGVtZSA8LSBjKCIjQzFCRUJGIiwiI2ZlNjEwMCIpCgpmcC5NdWMyIDwtIEZlYXR1cmVQbG90KGludGVncmF0ZWQscmVkdWN0aW9uPSJ1bWFwIixmZWF0dXJlcz0iTXVjMiIsY29scz1jb2xvclNjaGVtZSwgc2xvdCA9ICJkYXRhIixsYWJlbD1UUlVFLCByZXBlbD1UUlVFLGxhYmVsLnNpemU9NCkKZnAuTXVjMgoKZnAuVGZmMyA8LSBGZWF0dXJlUGxvdChpbnRlZ3JhdGVkLHJlZHVjdGlvbj0idW1hcCIsZmVhdHVyZXM9IlRmZjMiLGNvbHM9Y29sb3JTY2hlbWUsIHNsb3QgPSAiZGF0YSIsbGFiZWw9VFJVRSwgcmVwZWw9VFJVRSxsYWJlbC5zaXplPTQpCmZwLlRmZjMKCmZwLkx5ejEgPC0gRmVhdHVyZVBsb3QoaW50ZWdyYXRlZCxyZWR1Y3Rpb249InVtYXAiLGZlYXR1cmVzPSJMeXoxIixjb2xzPWNvbG9yU2NoZW1lLCBzbG90ID0gImRhdGEiLGxhYmVsPVRSVUUsIHJlcGVsPVRSVUUsbGFiZWwuc2l6ZT00KQpmcC5MeXoxCgpmcC5EZWZhMzAgPC0gRmVhdHVyZVBsb3QoaW50ZWdyYXRlZCxyZWR1Y3Rpb249InVtYXAiLGZlYXR1cmVzPSJEZWZhMzAiLGNvbHM9Y29sb3JTY2hlbWUsIHNsb3QgPSAiZGF0YSIsbGFiZWw9VFJVRSwgcmVwZWw9VFJVRSxsYWJlbC5zaXplPTQpCmZwLkRlZmEzMAoKZnAuQ2hnYSA8LSBGZWF0dXJlUGxvdChpbnRlZ3JhdGVkLHJlZHVjdGlvbj0idW1hcCIsZmVhdHVyZXM9IkNoZ2EiLGNvbHM9Y29sb3JTY2hlbWUsIHNsb3QgPSAiZGF0YSIsbGFiZWw9VFJVRSwgcmVwZWw9VFJVRSxsYWJlbC5zaXplPTQpCmZwLkNoZ2EKCmZwLlJlZzNhIDwtIEZlYXR1cmVQbG90KGludGVncmF0ZWQscmVkdWN0aW9uPSJ1bWFwIixmZWF0dXJlcz0iUmVnM2EiLGNvbHM9Y29sb3JTY2hlbWUsIHNsb3QgPSAiZGF0YSIsbGFiZWw9VFJVRSwgcmVwZWw9VFJVRSxsYWJlbC5zaXplPTQpCmZwLlJlZzNhCgpmcC5BbHBpIDwtIEZlYXR1cmVQbG90KGludGVncmF0ZWQscmVkdWN0aW9uPSJ1bWFwIixmZWF0dXJlcz0iQWxwaSIsY29scz1jb2xvclNjaGVtZSwgc2xvdCA9ICJkYXRhIixsYWJlbD1UUlVFLCByZXBlbD1UUlVFLGxhYmVsLnNpemU9NCkKZnAuQWxwaQoKZnAuQXRvaDEgPC0gRmVhdHVyZVBsb3QoaW50ZWdyYXRlZCxyZWR1Y3Rpb249InVtYXAiLGZlYXR1cmVzPSJBdG9oMSIsY29scz1jb2xvclNjaGVtZSwgc2xvdCA9ICJkYXRhIixsYWJlbD1UUlVFLCByZXBlbD1UUlVFLGxhYmVsLnNpemU9NCkKZnAuQXRvaDEKCmZwLkxncjUgPC0gRmVhdHVyZVBsb3QoaW50ZWdyYXRlZCxyZWR1Y3Rpb249InVtYXAiLGZlYXR1cmVzPSJMZ3I1Iixjb2xzPWNvbG9yU2NoZW1lLCBzbG90ID0gImRhdGEiLGxhYmVsPVRSVUUsIHJlcGVsPVRSVUUsbGFiZWwuc2l6ZT00KQpmcC5MZ3I1CgpmcC5TbW9jMiA8LSBGZWF0dXJlUGxvdChpbnRlZ3JhdGVkLHJlZHVjdGlvbj0idW1hcCIsZmVhdHVyZXM9IlNtb2MyIixjb2xzPWNvbG9yU2NoZW1lLCBzbG90ID0gImRhdGEiLGxhYmVsPVRSVUUsIHJlcGVsPVRSVUUsbGFiZWwuc2l6ZT00KQpmcC5TbW9jMgpgYGAKCmBgYHtyLGZpZy53aWR0aD0yMCxmaWcuaGVpZ2h0PTEwfQpmaWdTNEEgPC0gZ2dhcnJhbmdlKGZwLk11YzIsZnAuVGZmMyxmcC5MeXoxLGZwLkRlZmEzMCxmcC5DaGdhLGZwLlJlZzNhLGZwLkFscGksZnAuQXRvaDEsZnAuTGdyNSxmcC5TbW9jMiwgbGVnZW5kID0gInJpZ2h0IiwgbmNvbCA9IDUsIG5yb3cgPSAyKQoKZmlnUzRBCgojcGRmKCdGaWdTNEFfY2JTYWZlLnBkZicsd2lkdGg9MjAsIGhlaWdodD0xMCkKI2ZpZ1M0QQojZGV2Lm9mZigpCmBgYAoKIyMgRmlndXJlIDVFIC0gY2VsbCBjeWNsZSBkYXRhIC0gY29sb3IgYmxpbmQgc2FmZQoKYGBge3J9CkRlZmF1bHRBc3NheShpbnRlZ3JhdGVkKTwtIlJOQSIKZ2VuZS5uYW1lcyA8LSByb3duYW1lcyhpbnRlZ3JhdGVkQGFzc2F5cyRSTkFAZGF0YSkKSWRlbnRzKG9iamVjdCA9IGludGVncmF0ZWQpIDwtIGludGVncmF0ZWQkc2V1cmF0X2NsdXN0ZXJzCnN0ZW0uc3Vic2V0IDwtIHN1YnNldChpbnRlZ3JhdGVkLCBpZGVudHMgPSBjKCIyIiwiNSIsIjEwIikpCmxldmVscyhzdGVtLnN1YnNldCkgPC0gYygiNSIsIjIiLCIxMCIpCgp2bG5fY29sb3JzIDwtIGMoIjIiPSIjMTE3NzMzIiwKICAgICAgICAgICAgICAgICI1Ij0iIzk5OTkzMyIsCiAgICAgICAgICAgICAgICAiMTAiPSIjMDA5RTczIikKICAKcy5JbkRhdGEgPC0gaW50ZXJzZWN0KGdlbmUubmFtZXMsR09JLmxpc3RzJG1tLnMpCmcybS5JbkRhdGEgPC0gaW50ZXJzZWN0KGdlbmUubmFtZXMsR09JLmxpc3RzJG1tLmcybSkKc3RlbS5zdWJzZXRbWyJwZXJjZW50Lm1tLnMiXV0gPC0gUGVyY2VudGFnZUZlYXR1cmVTZXQoc3RlbS5zdWJzZXQsIGZlYXR1cmVzID0gcy5JbkRhdGEpCnN0ZW0uc3Vic2V0W1sicGVyY2VudC5tbS5nMm0iXV0gPC0gUGVyY2VudGFnZUZlYXR1cmVTZXQoc3RlbS5zdWJzZXQsIGZlYXR1cmVzID0gZzJtLkluRGF0YSkKbW0ucyA8LSBWbG5QbG90KHN0ZW0uc3Vic2V0LCBjb2xzID0gdmxuX2NvbG9ycywgZmVhdHVyZXM9InBlcmNlbnQubW0ucyIscHQuc2l6ZSA9IDAuMyxzbG90ID0gImRhdGEiKQptbS5zCm1tLmcybSA8LSBWbG5QbG90KHN0ZW0uc3Vic2V0LCBjb2xzID0gdmxuX2NvbG9ycywgZmVhdHVyZXM9InBlcmNlbnQubW0uZzJtIixwdC5zaXplID0gMC4zLHNsb3QgPSAiZGF0YSIpCm1tLmcybQoKZmlnUzRiIDwtIGdnYXJyYW5nZShtbS5zLG1tLmcybSwgbGVnZW5kID0gRkFMU0UsIG5jb2w9MiwgbnJvdz0xKQpmaWdTNGIKCnBkZignZmlnUzRiX2NiU2FmZS5wZGYnLHdpZHRoPTgsIGhlaWdodD00KQpmaWdTNGIKZGV2Lm9mZigpCgppbnRlZ3JhdGVkW1sicGVyY2VudC5tbS5zIl1dIDwtIFBlcmNlbnRhZ2VGZWF0dXJlU2V0KGludGVncmF0ZWQsIGZlYXR1cmVzID0gcy5JbkRhdGEpCmludGVncmF0ZWRbWyJwZXJjZW50Lm1tLmcybSJdXSA8LSBQZXJjZW50YWdlRmVhdHVyZVNldChpbnRlZ3JhdGVkLCBmZWF0dXJlcyA9IGcybS5JbkRhdGEpCgptbS5nMm0uRmxhZyA8LSBpZl9lbHNlKGludGVncmF0ZWRAbWV0YS5kYXRhJHBlcmNlbnQubW0uZzJtID49IDAuMywgIlllcyIsICJObyIpCmludGVncmF0ZWRAbWV0YS5kYXRhJG1tLmcybS5GbGFnIDwtIG1tLmcybS5GbGFnCgpwIDwtIHRhYmxlKGludGVncmF0ZWQkY2x1c3RfdHJlYXQsaW50ZWdyYXRlZCRtbS5nMm0uRmxhZykKcC5nMm0uc3VtbWFyeSA8LSByb3VuZChwcm9wLnRhYmxlKHAsMiksMykKCm1tLnMuRmxhZyA8LSBpZl9lbHNlKGludGVncmF0ZWRAbWV0YS5kYXRhJHBlcmNlbnQubW0ucyA+PSAwLjIsICJZZXMiLCAiTm8iKQppbnRlZ3JhdGVkQG1ldGEuZGF0YSRtbS5zLkZsYWcgPC0gbW0ucy5GbGFnCgpwIDwtIHRhYmxlKGludGVncmF0ZWQkY2x1c3RfdHJlYXQsaW50ZWdyYXRlZCRtbS5zLkZsYWcpCnAucy5zdW1tYXJ5IDwtIHJvdW5kKHByb3AudGFibGUocCwxKSwzKQpgYGAKCiMjIGVzY2FwZSBzc0dTRUEgLSBydW4gc3NHU0VBIHRvIHF1YW50aWZ5IGV4cHJlc3Npb24gb2YgdGhlIEJpdG9uSSBnZW5lIHNldCBjbHVzdGVycwoKVGhpcyBjb2RlIGlzIG5vIGxvbmdlciB3b3JraW5nIGR1ZSB0byBSIGFuZCBwYWNrYWdlIHVwZGF0ZXMgYnV0IHJlc3VsdGluZyBkYXRhIGlzIHN0b3JlZCBpbiB0aGUgc2V1cmF0IG9iamVjdAplc2NhcGUgMS4wLjAgaXMgcHJvYmFibHkgcmVxdWlyZWQgYnV0IGlzIG5vIGxvbmdlciBhdmFpbGFibGUuIHRoZSB2ZXJzaW9uIGluIHRoaXMgUiBpbWFnZSBpcyAxLjAuMQogZXNjYXBlIHNzR1NFQSAtIHJ1biBzc0dTRUEgdG8gcXVhbnRpZnkgZXhwcmVzc2lvbiBvZiB0aGUgQml0b25JIGdlbmUgc2V0IGNsdXN0ZXJzCgpgYGB7cn0KI2VncyA8LSBHZW5lU2V0KEdPSS5saXN0cyRCaXRvbl9TMV9JU0MuSSwgc2V0TmFtZT0iQml0b25JIikKI0VTIDwtIGVucmljaEl0KG9iaiA9IGludGVncmF0ZWQsIGdlbmUuc2V0cyA9IGVncywgZ3JvdXBzID0gMTAwMCwgY29yZXMgPSA0KQojaW50ZWdyYXRlZEBtZXRhLmRhdGEkQml0b25JX3NzR1NFQSA8LSBFUyRCaXRvbkkKYGBgCgojIyBlc2NhcGUgc3NHU0VBIC0gcnVuIHNzR1NFQSB0byBxdWFudGlmeSBleHByZXNzaW9uIG9mIHRoZSBCaXRvbklJIGdlbmUgc2V0IGNsdXN0ZXJzCgpgYGB7cn0KIyBlZ3MgPC0gR2VuZVNldChHT0kubGlzdHMkQml0b25fUzFfSVNDLklJLCBzZXROYW1lPSJCaXRvbklJIikKIyBFUyA8LSBlbnJpY2hJdChvYmogPSBpbnRlZ3JhdGVkLCBnZW5lLnNldHMgPSBlZ3MsIGdyb3VwcyA9IDEwMDAsIGNvcmVzID0gNCkKIyBpbnRlZ3JhdGVkQG1ldGEuZGF0YSRCaXRvbklJX3NzR1NFQSA8LSBFUyRCaXRvbklJCmBgYAoKIyMgZXNjYXBlIHNzR1NFQSAtIHJ1biBzc0dTRUEgdG8gcXVhbnRpZnkgZXhwcmVzc2lvbiBvZiB0aGUgQml0b25JSUkgZ2VuZSBzZXQgY2x1c3RlcnMKCmBgYHtyfQojIGVncyA8LSBHZW5lU2V0KEdPSS5saXN0cyRCaXRvbl9TMV9JU0MuSUlJLCBzZXROYW1lPSJCaXRvbklJSSIpCiMgRVMgPC0gZW5yaWNoSXQob2JqID0gaW50ZWdyYXRlZCwgZ2VuZS5zZXRzID0gZWdzLCBncm91cHMgPSAxMDAwLCBjb3JlcyA9IDQpCiMgaW50ZWdyYXRlZEBtZXRhLmRhdGEkQml0b25JSUlfc3NHU0VBIDwtIEVTJEJpdG9uSUlJCmBgYAoKIyMgRXh0ZW5kZWQgZGF0YSA1IHBsb3RzIC0gY29sb3JibGluZCBzYWZlCgogRmlndXJlIDVHIC0gQml0b24gMSBpbiBjbHVzdGVyNSoKIEZpZ3VyZSA1R19JSSAtIEJpdG9uIElJIGluIGNsdXN0ZXIyKgogRmlndXJlIDVHX0lJSSAtIEJpdG9uIElJSSBpbiBjbHVzdGVyMTAqCiBGaWd1cmUgNUggLSBQZGdmYSBpbiBjbHVzdGVyNSoKIEZpZ3VyZSBTM0UgLSBHa24zIGluIGNsdXN0ZXI1KgogCgpgYGB7cixmaWcud2lkdGg9NCxmaWcuaGVpZ2h0PTR9CklkZW50cyhvYmplY3QgPSBpbnRlZ3JhdGVkKSA8LSBpbnRlZ3JhdGVkJHNldXJhdF9jbHVzdGVycwpjbHVzdDUuc3Vic2V0IDwtIHN1YnNldChpbnRlZ3JhdGVkLCBpZGVudHMgPSBjKCI1IikpCklkZW50cyhvYmplY3QgPSBjbHVzdDUuc3Vic2V0KSA8LSBjbHVzdDUuc3Vic2V0JHRyZWF0X2NsdXN0Cgp2bG5fY29sb3JzIDwtIGMoImFsNSI9IiNlNjlmMDAiLAogICAgICAgICAgICAgICAgImY1Ij0iIzU2YjRmOSIsCiAgICAgICAgICAgICAgICAicmY1Ij0iIzExNzczMyIsCiAgICAgICAgICAgICAgICAicmYucmFwYTUiPSIjZDU1ZTAwIikKCnBsb3Qub3JkZXIgPC0gYygiYWw1IiwiZjUiLCJyZjUiLCJyZi5yYXBhNSIpCklkZW50cyhvYmplY3QgPSBjbHVzdDUuc3Vic2V0KSA8LSBmYWN0b3IoSWRlbnRzKG9iamVjdCA9IGNsdXN0NS5zdWJzZXQpLCBsZXZlbHMgPSBwbG90Lm9yZGVyKQp2bG4uQml0b25JLnNzR1NFQSA8LSBWbG5QbG90KGNsdXN0NS5zdWJzZXQsIGNvbHMgPSB2bG5fY29sb3JzLCBmZWF0dXJlcz0iQml0b25JX3NzR1NFQSIsc2xvdCA9ICJkYXRhIixwdC5zaXplID0gMC40KSArIAogIHN0YXRfc3VtbWFyeShmdW4gPSBtZWRpYW4sIGdlb209J3BvaW50Jywgc2l6ZSA9IDE1LCBjb2xvdXIgPSAiYmxhY2siLCBzaGFwZSA9IDk1KSArIE5vTGVnZW5kKCkgKyB5bGFiKCJFbnJpY2htZW50IFNjb3JlIikgKyBnZ3RpdGxlKCJCaXRvbiBJU0MtSV9zc0dTRUEiKQoKdmxuLkJpdG9uSS5zc0dTRUEKCiNwZGYoJ0ZpZzVHLnBkZicsd2lkdGg9NCwgaGVpZ2h0PTQpCiN2bG4uQml0b25JLnNzR1NFQQojZGV2Lm9mZigpCgp2bG4uUGRnZmEgPC0gVmxuUGxvdChjbHVzdDUuc3Vic2V0LCBjb2xzID0gdmxuX2NvbG9ycywgZmVhdHVyZXMgPSBjKCJQZGdmYSIpLCBzbG90PSAiZGF0YSIscHQuc2l6ZSA9IDAuNCkgKyBOb0xlZ2VuZCgpCnZsbi5QZGdmYQoKcGRmKCdGaWdTNGdfY2JTYWZlLnBkZicsd2lkdGg9NCwgaGVpZ2h0PTQpCnZsbi5QZGdmYQpkZXYub2ZmKCkKCnZsbi5Ha24zIDwtIFZsblBsb3QoY2x1c3Q1LnN1YnNldCwgY29scyA9IHZsbl9jb2xvcnMsIGZlYXR1cmVzID0gYygiR2tuMyIpLCBzbG90PSAiZGF0YSIscHQuc2l6ZSA9IDAuNCkgKyBOb0xlZ2VuZCgpCnZsbi5Ha24zCgpwZGYoJ0ZpZ1M0aF9jYlNhZmUucGRmJyx3aWR0aD00LCBoZWlnaHQ9NCkKdmxuLkdrbjMKZGV2Lm9mZigpCgpjbHVzdDIuc3Vic2V0IDwtIHN1YnNldChpbnRlZ3JhdGVkLCBpZGVudHMgPSBjKCIyIikpCklkZW50cyhvYmplY3QgPSBjbHVzdDIuc3Vic2V0KSA8LSBjbHVzdDIuc3Vic2V0JHRyZWF0X2NsdXN0Cgp2bG5fY29sb3JzIDwtIGMoImFsMiI9IiNlNjlmMDAiLAogICAgICAgICAgICAgICAgImYyIj0iIzU2YjRmOSIsCiAgICAgICAgICAgICAgICAicmYyIj0iIzExNzczMyIsCiAgICAgICAgICAgICAgICAicmYucmFwYTIiPSIjZDU1ZTAwIikKCnBsb3Qub3JkZXIgPC0gYygiYWwyIiwiZjIiLCJyZjIiLCJyZi5yYXBhMiIpCklkZW50cyhvYmplY3QgPSBjbHVzdDIuc3Vic2V0KSA8LSBmYWN0b3IoSWRlbnRzKG9iamVjdCA9IGNsdXN0Mi5zdWJzZXQpLCBsZXZlbHMgPSBwbG90Lm9yZGVyKQp2bG4uQml0b25JSS5zc0dTRUEgPC0gVmxuUGxvdChjbHVzdDIuc3Vic2V0LCBjb2xzID0gdmxuX2NvbG9ycywgZmVhdHVyZXM9IkJpdG9uSUlfc3NHU0VBIixzbG90ID0gImRhdGEiLHB0LnNpemUgPSAwLjQpICsgCiAgc3RhdF9zdW1tYXJ5KGZ1biA9IG1lZGlhbiwgZ2VvbT0ncG9pbnQnLCBzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIsIHNoYXBlID0gOTUpICsgTm9MZWdlbmQoKSArIHlsYWIoIkVucmljaG1lbnQgU2NvcmUiKSArIGdndGl0bGUoIkJpdG9uIElTQy1JSV9zc0dTRUEiKQp2bG4uQml0b25JSS5zc0dTRUEKCiNwZGYoJ0ZpZzVHX0lJLnBkZicsd2lkdGg9NCwgaGVpZ2h0PTQpCiN2bG4uQml0b25JSS5zc0dTRUEKI2Rldi5vZmYoKQoKY2x1c3QxMC5zdWJzZXQgPC0gc3Vic2V0KGludGVncmF0ZWQsIGlkZW50cyA9IGMoIjEwIikpCklkZW50cyhvYmplY3QgPSBjbHVzdDEwLnN1YnNldCkgPC0gY2x1c3QxMC5zdWJzZXQkdHJlYXRfY2x1c3QKCnZsbl9jb2xvcnMgPC0gYygiYWwxMCI9IiNlNjlmMDAiLAogICAgICAgICAgICAgICAgImYxMCI9IiM1NmI0ZjkiLAogICAgICAgICAgICAgICAgInJmMTAiPSIjMTE3NzMzIiwKICAgICAgICAgICAgICAgICJyZi5yYXBhMTAiPSIjZDU1ZTAwIikKCnBsb3Qub3JkZXIgPC0gYygiYWwxMCIsImYxMCIsInJmMTAiLCJyZi5yYXBhMTAiKQpJZGVudHMob2JqZWN0ID0gY2x1c3QxMC5zdWJzZXQpIDwtIGZhY3RvcihJZGVudHMob2JqZWN0ID0gY2x1c3QxMC5zdWJzZXQpLCBsZXZlbHMgPSBwbG90Lm9yZGVyKQp2bG4uQml0b25JSUkuc3NHU0VBIDwtIFZsblBsb3QoY2x1c3QxMC5zdWJzZXQsIGNvbHMgPSB2bG5fY29sb3JzLCBmZWF0dXJlcz0iQml0b25JSUlfc3NHU0VBIixzbG90ID0gImRhdGEiLHB0LnNpemUgPSAwLjQpICsgCiAgc3RhdF9zdW1tYXJ5KGZ1biA9IG1lZGlhbiwgZ2VvbT0ncG9pbnQnLCBzaXplID0gMTUsIGNvbG91ciA9ICJibGFjayIsIHNoYXBlID0gOTUpICsgTm9MZWdlbmQoKSArIHlsYWIoIkVucmljaG1lbnQgU2NvcmUiKSArIGdndGl0bGUoIkJpdG9uIElTQy1JSUlfc3NHU0VBIikKdmxuLkJpdG9uSUlJLnNzR1NFQQoKI3BkZignRmlnNUdfSUlJLnBkZicsd2lkdGg9NCwgaGVpZ2h0PTQpCiN2bG4uQml0b25JSUkuc3NHU0VBCiNkZXYub2ZmKCkKYGBgCgojIyBCaXRvbiBwbG90cyBhc3NlbWJsZWQKCmBgYHtyLGZpZy5oZWlnaHQ9NSxmaWcud2lkdGg9MTB9CmJpdG9uUGxvdCA8LSBnZ2FycmFuZ2UodmxuLkJpdG9uSS5zc0dTRUEsdmxuLkJpdG9uSUkuc3NHU0VBLHZsbi5CaXRvbklJSS5zc0dTRUEsbnJvdz0xLG5jb2w9MykKYml0b25QbG90IAoKI3BkZignRmlnUzRmX2NiU2FmZS5wZGYnLHdpZHRoPTEwLCBoZWlnaHQ9NSkKI2JpdG9uUGxvdAojZGV2Lm9mZigpCmBgYAoKIyMgRmlnIDVIIHN0eWxlIHBsb3RzIGZvciBPYXQKIyMjIEZpZ3VyZSA1SCBzdHlsZSBwbG90cyBmb3IgT2F0LCBPY3QsIEFzcyBBc2wgaW4gY2x1c3RlcjUKCmBgYHtyfQpEZWZhdWx0QXNzYXkoaW50ZWdyYXRlZCk8LSJSTkEiCklkZW50cyhvYmplY3QgPSBpbnRlZ3JhdGVkKSA8LSBpbnRlZ3JhdGVkJHNldXJhdF9jbHVzdGVycwpjbHVzdDUuc3Vic2V0IDwtIHN1YnNldChpbnRlZ3JhdGVkLCBpZGVudHMgPSBjKCI1IikpCklkZW50cyhvYmplY3QgPSBjbHVzdDUuc3Vic2V0KSA8LSBjbHVzdDUuc3Vic2V0JHRyZWF0X2NsdXN0CmxldmVscyhjbHVzdDUuc3Vic2V0KSA8LSBjKCJhbDUiLCJmNSIsInJmNSIsInJmLnJhcGE1IikKY2x1c3Q1LnN1YnNldCR0cmVhdF9jbHVzdCA8LSBmYWN0b3IoeCA9IGNsdXN0NS5zdWJzZXQkdHJlYXRfY2x1c3QsIGxldmVscyA9IGMoImFsNSIsImY1IiwicmY1IiwicmYucmFwYTUiKSkKVmxuUGxvdChjbHVzdDUuc3Vic2V0LCBmZWF0dXJlcyA9IGMoIk9hdCIpLCBzcGxpdC5ieSA9ICJ0cmVhdF9jbHVzdCIsIGdyb3VwLmJ5ID0gInRyZWF0X2NsdXN0Iiwgc2xvdD0gImRhdGEiLHB0LnNpemUgPSAwLjUpCgp2bG4uT2F0LjUgPC0gVmxuUGxvdChjbHVzdDUuc3Vic2V0LCBmZWF0dXJlcyA9IGMoIk9hdCIpLCBzbG90PSAiZGF0YSIscHQuc2l6ZSA9IDAuMSkKdmxuLk9hdC41CgojcGRmKCdGaWc1SF9PYXQuNS5wZGYnLHdpZHRoPTQsIGhlaWdodD00KQojdmxuLk9hdC41CiNkZXYub2ZmKCkKCmNsdXN0Mi5zdWJzZXQgPC0gc3Vic2V0KGludGVncmF0ZWQsIGlkZW50cyA9IGMoIjIiKSkKSWRlbnRzKG9iamVjdCA9IGNsdXN0Mi5zdWJzZXQpIDwtIGNsdXN0Mi5zdWJzZXQkdHJlYXRfY2x1c3QKbGV2ZWxzKGNsdXN0Mi5zdWJzZXQpIDwtIGMoImFsMiIsImYyIiwicmYyIiwicmYucmFwYTIiKQpjbHVzdDIuc3Vic2V0JHRyZWF0X2NsdXN0IDwtIGZhY3Rvcih4ID0gY2x1c3QyLnN1YnNldCR0cmVhdF9jbHVzdCwgbGV2ZWxzID0gYygiYWwyIiwiZjIiLCJyZjIiLCJyZi5yYXBhMiIpKQpWbG5QbG90KGNsdXN0Mi5zdWJzZXQsIGZlYXR1cmVzID0gYygiT2F0IiksIHNwbGl0LmJ5ID0gInRyZWF0X2NsdXN0IiwgZ3JvdXAuYnkgPSAidHJlYXRfY2x1c3QiLCBzbG90PSAiZGF0YSIscHQuc2l6ZSA9IDAuNSkKCnZsbi5PYXQuMiA8LSBWbG5QbG90KGNsdXN0Mi5zdWJzZXQsIGZlYXR1cmVzID0gYygiT2F0IiksIHNsb3Q9ICJkYXRhIixwdC5zaXplID0gMC4xKQp2bG4uT2F0LjIKCiNwZGYoJ0ZpZzVIX09hdC4yLnBkZicsd2lkdGg9NCwgaGVpZ2h0PTQpCiN2bG4uT2F0LjIKI2Rldi5vZmYoKQoKY2x1c3QxMC5zdWJzZXQgPC0gc3Vic2V0KGludGVncmF0ZWQsIGlkZW50cyA9IGMoIjEwIikpCklkZW50cyhvYmplY3QgPSBjbHVzdDEwLnN1YnNldCkgPC0gY2x1c3QxMC5zdWJzZXQkdHJlYXRfY2x1c3QKbGV2ZWxzKGNsdXN0MTAuc3Vic2V0KSA8LSBjKCJhbDEwIiwiZjEwIiwicmYxMCIsInJmLnJhcGExMCIpCmNsdXN0MTAuc3Vic2V0JHRyZWF0X2NsdXN0IDwtIGZhY3Rvcih4ID0gY2x1c3QxMC5zdWJzZXQkdHJlYXRfY2x1c3QsIGxldmVscyA9IGMoImFsMTAiLCJmMTAiLCJyZjEwIiwicmYucmFwYTEwIikpClZsblBsb3QoY2x1c3QxMC5zdWJzZXQsIGZlYXR1cmVzID0gYygiT2F0IiksIHNwbGl0LmJ5ID0gInRyZWF0X2NsdXN0IiwgZ3JvdXAuYnkgPSAidHJlYXRfY2x1c3QiLCBzbG90PSAiZGF0YSIscHQuc2l6ZSA9IDAuNSkKCiN2bG4uT2F0LjEwIDwtIFZsblBsb3QoY2x1c3QxMC5zdWJzZXQsIGZlYXR1cmVzID0gYygiT2F0IiksIHNsb3Q9ICJkYXRhIixwdC5zaXplID0gMC4xKQojdmxuLk9hdC4xMAoKI3BkZignRmlnNUhfT2F0LjEwLnBkZicsd2lkdGg9NCwgaGVpZ2h0PTQpCiN2bG4uT2F0LjEwCiNkZXYub2ZmKCkKCkRlZmF1bHRBc3NheShpbnRlZ3JhdGVkKTwtIlJOQSIKSWRlbnRzKG9iamVjdCA9IGludGVncmF0ZWQpIDwtIGludGVncmF0ZWQkc2V1cmF0X2NsdXN0ZXJzCmNsdXN0NS4yLjEwLnN1YnNldCA8LSBzdWJzZXQoaW50ZWdyYXRlZCwgaWRlbnRzID0gYygiNSIsIjIiLCIxMCIpKQpJZGVudHMob2JqZWN0ID0gY2x1c3Q1LjIuMTAuc3Vic2V0KSA8LSBjbHVzdDUuMi4xMC5zdWJzZXQkdHJlYXRfY2x1c3QKbGV2ZWxzKGNsdXN0NS4yLjEwLnN1YnNldCkgPC0gYygiYWw1IiwiZjUiLCJyZjUiLCJyZi5yYXBhNSIsImFsMiIsImYyIiwicmYyIiwicmYucmFwYTIiLCJhbDEwIiwiZjEwIiwicmYxMCIsInJmLnJhcGExMCIpCmNsdXN0NS4yLjEwLnN1YnNldCR0cmVhdF9jbHVzdCA8LSBmYWN0b3IoeCA9IGNsdXN0NS4yLjEwLnN1YnNldCR0cmVhdF9jbHVzdCwgbGV2ZWxzID0gYygiYWw1IiwiZjUiLCJyZjUiLCJyZi5yYXBhNSIsImFsMiIsImYyIiwicmYyIiwicmYucmFwYTIiLCJhbDEwIiwiZjEwIiwicmYxMCIsInJmLnJhcGExMCIpKQpWbG5QbG90KGNsdXN0NS4yLjEwLnN1YnNldCwgZmVhdHVyZXMgPSBjKCJPYXQiKSwgc3BsaXQuYnkgPSAidHJlYXRfY2x1c3QiLCBncm91cC5ieSA9ICJ0cmVhdF9jbHVzdCIsIHNsb3Q9ICJkYXRhIixwdC5zaXplID0gMC41KQoKdmxuLk9hdC41LjIuMTAgPC0gVmxuUGxvdChjbHVzdDUuMi4xMC5zdWJzZXQsIGZlYXR1cmVzID0gYygiT2F0IiksIHNsb3Q9ICJkYXRhIixwdC5zaXplID0gMC4xKQp2bG4uT2F0LjUuMi4xMAoKI3BkZignRmlnNUhfT2F0LjUuMi4xMC5wZGYnLHdpZHRoPTEyLCBoZWlnaHQ9NCkKI3Zsbi5PYXQuNS4yLjEwCiNkZXYub2ZmKCkKYGBgCgojIyBGaWd1cmUgNUggc3R5bGUgcGxvdHMgYnV0IHdpdGhvdXQgY2x1c3RlciBmb3IgT2F0KgoKYGBge3J9CkRlZmF1bHRBc3NheShpbnRlZ3JhdGVkKTwtIlJOQSIKSWRlbnRzKG9iamVjdCA9IGludGVncmF0ZWQpIDwtIGludGVncmF0ZWQkb3JpZy5pZGVudApsZXZlbHMoaW50ZWdyYXRlZCkgPC0gYygiYWwiLCJmIiwicmYiLCJyZi5yYXBhIikKaW50ZWdyYXRlZCRvcmlnLmlkZW50IDwtIGZhY3Rvcih4ID0gaW50ZWdyYXRlZCRvcmlnLmlkZW50LCBsZXZlbHMgPSBjKCJhbCIsImYiLCJyZiIsInJmLnJhcGEiKSkKVmxuUGxvdChpbnRlZ3JhdGVkLCBmZWF0dXJlcyA9IGMoIk9hdCIpLCBzcGxpdC5ieSA9ICJvcmlnLmlkZW50IiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIsIHNsb3Q9ICJkYXRhIixwdC5zaXplID0gMC41KQoKdmxuLk9hdC5ub2NsdXN0IDwtIFZsblBsb3QoaW50ZWdyYXRlZCwgZmVhdHVyZXMgPSBjKCJPYXQiKSwgc2xvdD0gImRhdGEiLHB0LnNpemUgPSAwLjEpCnZsbi5PYXQubm9jbHVzdAoKI3BkZignRmlnNUhfT2F0Lm5vY2x1c3QucGRmJyx3aWR0aD00LCBoZWlnaHQ9NCkKI3Zsbi5PYXQubm9jbHVzdAojZGV2Lm9mZigpCmBgYAoKIyMgRmlndXJlIFMzRSAtIERpZmZlcmVudGlhbCBFeHByZXNzaW9uIFRlc3RpbmcgdG8gcHJlcGFyZSAucm5rIGZpbGVzKgoKYGBge3J9CiMgRGVmYXVsdEFzc2F5KGludGVncmF0ZWQpPC0iUk5BIgojIElkZW50cyhvYmplY3QgPSBpbnRlZ3JhdGVkKSA8LSBpbnRlZ3JhdGVkJHRyZWF0X2NsdXN0CiMgbGV2ZWxzKHggPSBpbnRlZ3JhdGVkKQojICMjCiMgI2FkanVzdCB0aGUgaWQxIGFuZCBpZDIgdmFyaWFibGVzIHRvIHNldCB1cCBkaWZmZXJlbnQgdGVzdHMKIyAjY291bGQgdXNlIGEgbG9vcCBmb3IgdGhpcwojICMjCiMgaWQxIDwtICJhbDUiCiMgaWQyIDwtICJhbDIiCiMgb3V0RGF0YSA8LSBwYXN0ZShpZDEsaWQyLCJNYXJrZXJzIixzZXA9Ii4iKQojIG91dERhdGEgPC0gRmluZE1hcmtlcnMoaW50ZWdyYXRlZCwgaWRlbnQuMSA9IGlkMSwgaWRlbnQuMiA9IGlkMixsb2dmYy50aHJlc2hvbGQgPSAwLCBhc3NheT0iUk5BIikKIyBvdXREYXRhIDwtIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKG91dERhdGEsIiNNR0lTeW0iKQojIHJuay50bXAgPC0gb3V0RGF0YSAlPiUgZHBseXI6OnNlbGVjdChjKCIjTUdJU3ltIiwiYXZnX2xvZ0ZDIikpCiMgI3dyaXRlLnRhYmxlKHJuay50bXAsIHNlcD0nXHQnLGZpbGU9cGFzdGUwKGlkMSwiX3ZfIixpZDIsIi5ybmsiKSxjb2wubmFtZXM9VFJVRSwgcXVvdGU9RkFMU0UsIHJvdy5uYW1lcz1GQUxTRSkKIyAKIyBpZDEgPC0gImFsMTAiCiMgaWQyIDwtICJhbDIiCiMgb3V0RGF0YSA8LSBwYXN0ZShpZDEsaWQyLCJNYXJrZXJzIixzZXA9Ii4iKQojIG91dERhdGEgPC0gRmluZE1hcmtlcnMoaW50ZWdyYXRlZCwgaWRlbnQuMSA9IGlkMSwgaWRlbnQuMiA9IGlkMixsb2dmYy50aHJlc2hvbGQgPSAwLCBhc3NheT0iUk5BIikKIyBvdXREYXRhIDwtIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKG91dERhdGEsIiNNR0lTeW0iKQojIHJuay50bXAgPC0gb3V0RGF0YSAlPiUgZHBseXI6OnNlbGVjdChjKCIjTUdJU3ltIiwiYXZnX2xvZ0ZDIikpCiMgI3dyaXRlLnRhYmxlKHJuay50bXAsIHNlcD0nXHQnLGZpbGU9cGFzdGUwKGlkMSwiX3ZfIixpZDIsIi5ybmsiKSxjb2wubmFtZXM9VFJVRSwgcXVvdGU9RkFMU0UsIHJvdy5uYW1lcz1GQUxTRSkKIyAKIyBpZDEgPC0gImFsMTAiCiMgaWQyIDwtICJhbDUiCiMgb3V0RGF0YSA8LSBwYXN0ZShpZDEsaWQyLCJNYXJrZXJzIixzZXA9Ii4iKQojIG91dERhdGEgPC0gRmluZE1hcmtlcnMoaW50ZWdyYXRlZCwgaWRlbnQuMSA9IGlkMSwgaWRlbnQuMiA9IGlkMixsb2dmYy50aHJlc2hvbGQgPSAwLCBhc3NheT0iUk5BIikKIyBvdXREYXRhIDwtIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKG91dERhdGEsIiNNR0lTeW0iKQojIHJuay50bXAgPC0gb3V0RGF0YSAlPiUgZHBseXI6OnNlbGVjdChjKCIjTUdJU3ltIiwiYXZnX2xvZ0ZDIikpCiMgI3dyaXRlLnRhYmxlKHJuay50bXAsIHNlcD0nXHQnLGZpbGU9cGFzdGUwKGlkMSwiX3ZfIixpZDIsIi5ybmsiKSxjb2wubmFtZXM9VFJVRSwgcXVvdGU9RkFMU0UsIHJvdy5uYW1lcz1GQUxTRSkKYGBgCgojIFNhdmUgaW50ZWdyYXRlZCBvYmplY3Qgd2l0aCBzc0dTRUEgZGF0YQoKYGBge3J9CiNzYXZlKGludGVncmF0ZWQsIGZpbGU9ImludGVncmF0ZWRfZmluYWwuUm9iaiIpCmBgYAoKYGBge3J9CnNlc3Npb25JbmZvKCkKd3JpdGVMaW5lcyhjYXB0dXJlLm91dHB1dChzZXNzaW9uSW5mbygpKSwgIjIwMjRfc2Vzc2lvbkluZm8udHh0IikKYGBgCgo=